diff --git a/configure.ac b/configure.ac index e964cac02c..0ff9a295ba 100644 --- a/configure.ac +++ b/configure.ac @@ -686,12 +686,6 @@ AG_GST_CHECK_FEATURE(AALIB, [aalib ASCII Art library], aasink, [ AS_SCRUB_INCLUDE(AALIB_CFLAGS) ]) -dnl *** annodex *** -translit(dnm, m, l) AM_CONDITIONAL(USE_ANNODEX, true) -AG_GST_CHECK_FEATURE(ANNODEX, [XML library], annodex, [ - AG_GST_PKG_CHECK_MODULES(ANNODEX, libxml-2.0 >= 2.4.9) -]) - dnl *** cairo *** translit(dnm, m, l) AM_CONDITIONAL(USE_CAIRO, true) AG_GST_CHECK_FEATURE(CAIRO, [Cairo graphics rendering], cairo, [ @@ -954,7 +948,6 @@ else dnl not building plugins with external dependencies, dnl but we still need to set the conditionals AM_CONDITIONAL(USE_AALIB, false) -AM_CONDITIONAL(USE_ANNODEX, false) AM_CONDITIONAL(USE_BZ2, false) AM_CONDITIONAL(USE_CAIRO, false) AM_CONDITIONAL(USE_CAIRO_GOBJECT, false) @@ -1093,7 +1086,6 @@ gst/flx/Makefile gst/y4m/Makefile ext/Makefile ext/aalib/Makefile -ext/annodex/Makefile ext/cairo/Makefile ext/dv/Makefile ext/flac/Makefile diff --git a/docs/plugins/Makefile.am b/docs/plugins/Makefile.am index 5c73726beb..6ad095376c 100644 --- a/docs/plugins/Makefile.am +++ b/docs/plugins/Makefile.am @@ -53,8 +53,6 @@ IGNORE_CFILES = EXTRA_HFILES = \ $(top_srcdir)/ext/aalib/gstaasink.h \ - $(top_srcdir)/ext/annodex/gstcmmldec.h \ - $(top_srcdir)/ext/annodex/gstcmmlenc.h \ $(top_srcdir)/ext/cairo/gsttextoverlay.h \ $(top_srcdir)/ext/cairo/gsttimeoverlay.h \ $(top_srcdir)/ext/cairo/gstcairorender.h \ diff --git a/docs/plugins/gst-plugins-good-plugins-docs.sgml b/docs/plugins/gst-plugins-good-plugins-docs.sgml index cbedd70652..bac36223ec 100644 --- a/docs/plugins/gst-plugins-good-plugins-docs.sgml +++ b/docs/plugins/gst-plugins-good-plugins-docs.sgml @@ -57,8 +57,6 @@ - - @@ -187,7 +185,6 @@ - diff --git a/docs/plugins/gst-plugins-good-plugins-sections.txt b/docs/plugins/gst-plugins-good-plugins-sections.txt index d37038c95f..0dbe5746f9 100644 --- a/docs/plugins/gst-plugins-good-plugins-sections.txt +++ b/docs/plugins/gst-plugins-good-plugins-sections.txt @@ -540,38 +540,6 @@ GST_IS_CAPS_SETTER_CLASS gst_caps_setter_get_type -
-element-cmmldec -cmmldec -GstCmmlDec - -GstCmmlDecClass -GST_TYPE_CMML_DEC -GST_CMML_DEC -GST_CMML_DEC_CLASS -GST_CMML_DEC_GET_CLASS -GST_IS_CMML_DEC -GST_IS_CMML_DEC_CLASS -gst_cmml_dec_plugin_init -gst_cmml_dec_get_type -
- -
-element-cmmlenc -cmmlenc -GstCmmlEnc - -GstCmmlEncClass -GST_TYPE_CMML_ENC -GST_CMML_ENC -GST_CMML_ENC_CLASS -GST_CMML_ENC_GET_CLASS -GST_IS_CMML_ENC -GST_IS_CMML_ENC_CLASS -gst_cmml_enc_plugin_init -gst_cmml_enc_get_type -
-
element-cutter cutter diff --git a/docs/plugins/inspect/plugin-annodex.xml b/docs/plugins/inspect/plugin-annodex.xml deleted file mode 100644 index c7f44b7407..0000000000 --- a/docs/plugins/inspect/plugin-annodex.xml +++ /dev/null @@ -1,55 +0,0 @@ - - annodex - annodex stream manipulation (info about annodex: http://www.annodex.net) - ../../ext/annodex/.libs/libgstannodex.so - libgstannodex.so - 0.11.90 - LGPL - gst-plugins-good - GStreamer Good Plug-ins source release - Unknown package origin - - - cmmldec - CMML stream decoder - Codec/Decoder - Decodes CMML streams - Alessandro Decina <alessandro@nnva.org> - - - sink - sink - always -
text/x-cmml, encoded=(boolean)true
-
- - src - source - always -
text/x-cmml, encoded=(boolean)false
-
-
-
- - cmmlenc - CMML streams encoder - Codec/Encoder - Encodes CMML streams - Alessandro Decina <alessandro@nnva.org> - - - sink - sink - always -
text/x-cmml, encoded=(boolean)false
-
- - src - source - always -
text/x-cmml, encoded=(boolean)true
-
-
-
-
-
\ No newline at end of file diff --git a/ext/Makefile.am b/ext/Makefile.am index 791fe00254..96fa1360ec 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -4,12 +4,6 @@ else AALIB_DIR = endif -if USE_ANNODEX -ANNODEX_DIR = annodex -else -ANNODEX_DIR = -endif - if USE_CAIRO CAIRO_DIR = cairo else @@ -115,7 +109,6 @@ endif SUBDIRS = \ $(AALIB_DIR) \ - $(ANNODEX_DIR) \ $(CAIRO_DIR) \ $(DV1394_DIR) \ $(FLAC_DIR) \ @@ -136,7 +129,6 @@ SUBDIRS = \ DIST_SUBDIRS = \ aalib \ - annodex \ cairo \ dv \ flac \ diff --git a/ext/annodex/Makefile.am b/ext/annodex/Makefile.am deleted file mode 100644 index 0ce3f5d75c..0000000000 --- a/ext/annodex/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -plugin_LTLIBRARIES = libgstannodex.la - -# FIXME 0.11: ignore GValueArray warnings for now until this is sorted -ERROR_CFLAGS= - -libgstannodex_la_SOURCES = \ - gstannodex.c \ - gstcmmlutils.c \ - gstcmmldec.c \ - gstcmmlenc.c \ - gstcmmltag.c \ - gstcmmlparser.c - -libgstannodex_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) \ - $(GST_CFLAGS) $(ANNODEX_CFLAGS) -libgstannodex_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) \ - $(GST_LIBS) $(ANNODEX_LIBS) $(LIBM) -libgstannodex_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -libgstannodex_la_LIBTOOLFLAGS = --tag=disable-static - -noinst_HEADERS = gstannodex.h gstcmmlutils.h gstcmmltag.h gstcmmlparser.h \ - gstcmmldec.h gstcmmlenc.h diff --git a/ext/annodex/gstannodex.c b/ext/annodex/gstannodex.c deleted file mode 100644 index dd5f31eb4b..0000000000 --- a/ext/annodex/gstannodex.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * gstannodex.c - GStreamer annodex plugin - * Copyright (C) 2005 Alessandro Decina - * - * Authors: - * Alessandro Decina - * - * 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. - */ - -/* FIXME 0.11: suppress warnings for deprecated API such as GValueArray - * with newer GLib versions (>= 2.31.0) */ -#define GLIB_DISABLE_DEPRECATION_WARNINGS - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include -#include "gstannodex.h" -#include "gstcmmlparser.h" -#include "gstcmmlenc.h" -#include "gstcmmldec.h" - -GstClockTime -gst_annodex_granule_to_time (gint64 granulepos, gint64 granulerate_n, - gint64 granulerate_d, guint8 granuleshift) -{ - gint64 keyindex, keyoffset; - gint64 granulerate; - GstClockTime res; - - g_return_val_if_fail (granuleshift <= 64, GST_CLOCK_TIME_NONE); - - if (granulepos == -1) - return GST_CLOCK_TIME_NONE; - - if (granulepos == 0 || granulerate_n == 0 || granulerate_d == 0) - return 0; - - if (granuleshift != 0 && granuleshift != 64) { - keyindex = granulepos >> granuleshift; - keyoffset = granulepos - (keyindex << granuleshift); - granulepos = keyindex + keyoffset; - } - - /* GST_SECOND / (granulerate_n / granulerate_d) */ - granulerate = gst_util_uint64_scale (GST_SECOND, - granulerate_d, granulerate_n); - - /* granulepos * granulerate */ - res = gst_util_uint64_scale (granulepos, granulerate, 1); - - return res; -} - -GValueArray * -gst_annodex_parse_headers (const gchar * headers) -{ - GValueArray *array; - GValue val = { 0 }; - gchar *header_name = NULL; - gchar *header_value = NULL; - gchar *line, *column, *space, *tmp; - gchar **lines; - gint i = 0; - - array = g_value_array_new (0); - g_value_init (&val, G_TYPE_STRING); - - lines = g_strsplit (headers, "\r\n", 0); - line = lines[i]; - while (line != NULL && *line != '\0') { - if (line[0] == '\t' || line[0] == ' ') { - /* WSP: continuation line */ - if (header_value == NULL) - /* continuation line without a previous value */ - goto fail; - - tmp = g_strjoin (" ", header_value, g_strstrip (line), NULL); - g_free (header_value); - header_value = tmp; - } else { - if (header_name) { - g_value_take_string (&val, header_name); - g_value_array_append (array, &val); - g_value_take_string (&val, header_value); - g_value_array_append (array, &val); - } - /* search the column starting from line[1] as an header name can't be - * empty */ - column = g_strstr_len (line + 1, strlen (line) - 1, ":"); - if (column == NULL) - /* bad syntax */ - goto fail; - - if (*(space = column + 1) != ' ') - /* bad syntax */ - goto fail; - - header_name = g_strndup (line, column - line); - header_value = g_strdup (space + 1); - } - - line = lines[++i]; - } - - if (header_name) { - g_value_take_string (&val, header_name); - g_value_array_append (array, &val); - g_value_take_string (&val, header_value); - g_value_array_append (array, &val); - } - - g_value_unset (&val); - g_strfreev (lines); - - return array; - -fail: - GST_WARNING ("could not parse annodex headers"); - g_free (header_name); - g_free (header_value); - g_strfreev (lines); - g_value_array_free (array); - g_value_unset (&val); - return NULL; -} - -static gboolean -plugin_init (GstPlugin * plugin) -{ - gst_tag_register (GST_TAG_CMML_STREAM, GST_TAG_FLAG_META, - GST_TYPE_CMML_TAG_STREAM, "cmml-stream", "annodex CMML stream tag", NULL); - - gst_tag_register (GST_TAG_CMML_HEAD, GST_TAG_FLAG_META, - GST_TYPE_CMML_TAG_HEAD, "cmml-head", "annodex CMML head tag", NULL); - - gst_tag_register (GST_TAG_CMML_CLIP, GST_TAG_FLAG_META, - GST_TYPE_CMML_TAG_CLIP, "cmml-clip", "annodex CMML clip tag", NULL); - - gst_cmml_parser_init (); - - if (!gst_cmml_enc_plugin_init (plugin)) - return FALSE; - - if (!gst_cmml_dec_plugin_init (plugin)) - return FALSE; - - return TRUE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - annodex, - "annodex stream manipulation (info about annodex: http://www.annodex.net)", - plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) diff --git a/ext/annodex/gstannodex.h b/ext/annodex/gstannodex.h deleted file mode 100644 index ca35e367f5..0000000000 --- a/ext/annodex/gstannodex.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * gstannodex.h - GStreamer annodex utility functions - * Copyright (C) 2005 Alessandro Decina - * - * Authors: - * Alessandro Decina - * - * 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_ANNODEX_H__ -#define __GST_ANNODEX_H__ - -#include - -GstClockTime gst_annodex_granule_to_time (gint64 granulepos, - gint64 granulerate_n, gint64 granulerate_d, guint8 granuleshift); -gchar *gst_annodex_time_to_npt (GstClockTime time); -GValueArray *gst_annodex_parse_headers (const gchar * headers); - -#endif /* __GST_ANNODEX_H__ */ diff --git a/ext/annodex/gstcmmldec.c b/ext/annodex/gstcmmldec.c deleted file mode 100644 index a7b458f6cd..0000000000 --- a/ext/annodex/gstcmmldec.c +++ /dev/null @@ -1,695 +0,0 @@ -/* - * gstcmmldec.c - GStreamer annodex CMML decoder - * Copyright (C) 2005 Alessandro Decina - * - * Authors: - * Alessandro Decina - * - * 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-cmmldec - * @see_also: cmmlenc, oggdemux - * - * Cmmldec extracts a CMML document from a CMML bitstream.CMML is - * an XML markup language for time-continuous data maintained by the Annodex Foundation. - * - * - * Example pipeline - * |[ - * gst-launch -v filesrc location=annotated.ogg ! oggdemux ! cmmldec ! filesink location=annotations.cmml - * ]| - * - */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include -#include "gstannodex.h" -#include "gstcmmltag.h" -#include "gstcmmldec.h" -#include "gstcmmlutils.h" - -GST_DEBUG_CATEGORY_STATIC (cmmldec); -#define GST_CAT_DEFAULT cmmldec - -#define CMML_IDENT_HEADER_SIZE 29 - -enum -{ - ARG_0, - GST_CMML_DEC_WAIT_CLIP_END -}; - -enum -{ - LAST_SIGNAL -}; - -static GstStaticPadTemplate gst_cmml_dec_src_factory = -GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("text/x-cmml, encoded = (boolean) false") - ); - -static GstStaticPadTemplate gst_cmml_dec_sink_factory = -GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("text/x-cmml, encoded = (boolean) true") - ); - -/* GstCmmlDec */ -#define gst_cmml_dec_parent_class parent_class -G_DEFINE_TYPE (GstCmmlDec, gst_cmml_dec, GST_TYPE_ELEMENT); - -static void gst_cmml_dec_get_property (GObject * dec, guint property_id, - GValue * value, GParamSpec * pspec); -static void gst_cmml_dec_set_property (GObject * dec, guint property_id, - const GValue * value, GParamSpec * pspec); -static gboolean gst_cmml_dec_sink_query (GstPad * pad, GstObject * parent, - GstQuery * query); -static gboolean gst_cmml_dec_sink_event (GstPad * pad, GstObject * parent, - GstEvent * event); -static gboolean gst_cmml_dec_convert (GstPad * pad, GstFormat src_fmt, - gint64 src_val, GstFormat * dest_fmt, gint64 * dest_val); -static GstStateChangeReturn gst_cmml_dec_change_state (GstElement * element, - GstStateChange transition); -static GstFlowReturn gst_cmml_dec_chain (GstPad * pad, GstObject * parent, - GstBuffer * buffer); - -static GstCmmlPacketType gst_cmml_dec_parse_packet_type (GstCmmlDec * dec, - gchar * data, gsize size); -static void gst_cmml_dec_parse_ident_header (GstCmmlDec * dec, guint8 * data, - gsize size); -static void gst_cmml_dec_parse_first_header (GstCmmlDec * dec, guint8 * data, - gsize size); -static void gst_cmml_dec_parse_preamble (GstCmmlDec * dec, guchar * preamble, - guchar * cmml_root_element); -static void gst_cmml_dec_parse_xml (GstCmmlDec * dec, guchar * data, - guint size); -static void gst_cmml_dec_parse_head (GstCmmlDec * dec, GstCmmlTagHead * head); -static void gst_cmml_dec_parse_clip (GstCmmlDec * dec, GstCmmlTagClip * clip); - -static GstFlowReturn gst_cmml_dec_new_buffer (GstCmmlDec * dec, - guchar * data, gint size, GstBuffer ** buffer); -static void gst_cmml_dec_push_clip (GstCmmlDec * dec, GstCmmlTagClip * clip); -static void gst_cmml_dec_send_clip_tag (GstCmmlDec * dec, - GstCmmlTagClip * clip); - -static void gst_cmml_dec_finalize (GObject * object); - -static void -gst_cmml_dec_class_init (GstCmmlDecClass * klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - object_class->set_property = gst_cmml_dec_set_property; - object_class->get_property = gst_cmml_dec_get_property; - object_class->finalize = gst_cmml_dec_finalize; - - g_object_class_install_property (object_class, GST_CMML_DEC_WAIT_CLIP_END, - g_param_spec_boolean ("wait-clip-end-time", - "Wait clip end time", - "Send a tag for a clip when the clip ends, setting its end-time. " - "Use when you need to know both clip's start-time and end-time.", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - element_class->change_state = gst_cmml_dec_change_state; - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_cmml_dec_sink_factory)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_cmml_dec_src_factory)); - gst_element_class_set_static_metadata (element_class, "CMML stream decoder", - "Codec/Decoder", - "Decodes CMML streams", "Alessandro Decina "); -} - -static void -gst_cmml_dec_init (GstCmmlDec * dec) -{ - dec->sinkpad = - gst_pad_new_from_static_template (&gst_cmml_dec_sink_factory, "sink"); - gst_pad_set_chain_function (dec->sinkpad, gst_cmml_dec_chain); - gst_pad_set_query_function (dec->sinkpad, gst_cmml_dec_sink_query); - gst_pad_set_event_function (dec->sinkpad, gst_cmml_dec_sink_event); - gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad); - - dec->srcpad = - gst_pad_new_from_static_template (&gst_cmml_dec_src_factory, "src"); - gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad); - - dec->wait_clip_end = FALSE; -} - -static void -gst_cmml_dec_get_property (GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) -{ - GstCmmlDec *dec = GST_CMML_DEC (object); - - switch (property_id) { - case GST_CMML_DEC_WAIT_CLIP_END: - g_value_set_boolean (value, dec->wait_clip_end); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - -static void -gst_cmml_dec_set_property (GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) -{ - GstCmmlDec *dec = GST_CMML_DEC (object); - - switch (property_id) { - case GST_CMML_DEC_WAIT_CLIP_END: - dec->wait_clip_end = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (dec, property_id, pspec); - } -} - -static void -gst_cmml_dec_finalize (GObject * object) -{ - GstCmmlDec *dec = GST_CMML_DEC (object); - - if (dec->tracks) { - gst_cmml_track_list_destroy (dec->tracks); - dec->tracks = NULL; - } - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static GstStateChangeReturn -gst_cmml_dec_change_state (GstElement * element, GstStateChange transition) -{ - GstCmmlDec *dec = GST_CMML_DEC (element); - GstStateChangeReturn res; - - switch (transition) { - case GST_STATE_CHANGE_READY_TO_PAUSED: - dec->parser = gst_cmml_parser_new (GST_CMML_PARSER_DECODE); - dec->parser->user_data = dec; - dec->parser->preamble_callback = - (GstCmmlParserPreambleCallback) gst_cmml_dec_parse_preamble; - dec->parser->head_callback = - (GstCmmlParserHeadCallback) gst_cmml_dec_parse_head; - dec->parser->clip_callback = - (GstCmmlParserClipCallback) gst_cmml_dec_parse_clip; - dec->major = -1; - dec->minor = -1; - dec->granulerate_n = -1; - dec->granulerate_d = -1; - dec->granuleshift = 0; - dec->granulepos = 0; - dec->flow_return = GST_FLOW_OK; - dec->sent_root = FALSE; - dec->tracks = gst_cmml_track_list_new (); - break; - default: - break; - } - - res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PAUSED_TO_READY: - gst_cmml_parser_free (dec->parser); - gst_cmml_track_list_destroy (dec->tracks); - dec->tracks = NULL; - break; - default: - break; - } - - return res; -} - -static gboolean -gst_cmml_dec_sink_query (GstPad * pad, GstObject * parent, GstQuery * query) -{ - gboolean res = FALSE; - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_CONVERT: - { - GstFormat src_fmt, dest_fmt; - gint64 src_val, dest_val; - - gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val); - res = gst_cmml_dec_convert (pad, src_fmt, src_val, &dest_fmt, &dest_val); - if (res) - gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val); - break; - } - default: - break; - } - - return res; -} - -static gboolean -gst_cmml_dec_convert (GstPad * pad, - GstFormat src_fmt, gint64 src_val, GstFormat * dest_fmt, gint64 * dest_val) -{ - GstCmmlDec *dec = GST_CMML_DEC (GST_PAD_PARENT (pad)); - gboolean res = FALSE; - - switch (src_fmt) { - case GST_FORMAT_DEFAULT: - switch (*dest_fmt) { - case GST_FORMAT_TIME: - { - *dest_val = gst_annodex_granule_to_time (src_val, dec->granulerate_n, - dec->granulerate_d, dec->granuleshift); - res = TRUE; - break; - } - default: - break; - } - break; - default: - break; - } - - return res; -} - -static gboolean -gst_cmml_dec_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) -{ - GstCmmlDec *dec = GST_CMML_DEC (parent); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_EOS: - { - GstBuffer *buffer; - GstCmmlTagClip *clip; - GList *clips, *walk; - - GST_INFO_OBJECT (dec, "got EOS, flushing clips"); - - /* since we output a clip when the next one in the same track is found, on - * EOS we need to output the last clip (if any) of every track - */ - clips = gst_cmml_track_list_get_clips (dec->tracks); - for (walk = clips; walk; walk = g_list_next (walk)) { - clip = GST_CMML_TAG_CLIP (walk->data); - gst_cmml_dec_push_clip (dec, clip); - if (dec->wait_clip_end) { - clip->end_time = dec->timestamp; - gst_cmml_dec_send_clip_tag (dec, clip); - } - } - g_list_free (clips); - - /* send the cmml end tag */ - dec->flow_return = gst_cmml_dec_new_buffer (dec, - (guchar *) "", strlen (""), &buffer); - - if (dec->flow_return == GST_FLOW_OK) - dec->flow_return = gst_pad_push (dec->srcpad, buffer); - if (dec->flow_return == GST_FLOW_NOT_LINKED) - dec->flow_return = GST_FLOW_OK; /* Ignore NOT_LINKED */ - - break; - } - default: - break; - } - - return gst_pad_event_default (pad, parent, event); -} - -static GstFlowReturn -gst_cmml_dec_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) -{ - GstCmmlDec *dec = GST_CMML_DEC (parent); - GstCmmlPacketType packet; - GstMapInfo map; - guint8 *data; - gsize size; - - gst_buffer_map (buffer, &map, GST_MAP_READ); - data = map.data; - size = map.size; - - if (size == 0) { - /* the EOS page could be empty */ - dec->flow_return = GST_FLOW_OK; - goto done; - } - - dec->granulepos = GST_BUFFER_OFFSET_END (buffer); - dec->timestamp = gst_annodex_granule_to_time (dec->granulepos, - dec->granulerate_n, dec->granulerate_d, dec->granuleshift); - - /* identify the packet type */ - packet = gst_cmml_dec_parse_packet_type (dec, (gchar *) data, size); - - /* handle the packet. the handler will set dec->flow_return */ - switch (packet) { - case GST_CMML_PACKET_IDENT_HEADER: - if (dec->sent_root == FALSE) - /* don't parse the ident again in case of seeking to the beginning */ - gst_cmml_dec_parse_ident_header (dec, data, size); - break; - case GST_CMML_PACKET_FIRST_HEADER: - if (dec->sent_root == FALSE) - /* don't parse the xml preamble if it has already been parsed because it - * would error out, so seeking to the beginning would fail */ - gst_cmml_dec_parse_first_header (dec, data, size); - break; - case GST_CMML_PACKET_SECOND_HEADER: - case GST_CMML_PACKET_CLIP: - gst_cmml_dec_parse_xml (dec, data, size); - break; - case GST_CMML_PACKET_UNKNOWN: - default: - GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("unknown packet type")); - dec->flow_return = GST_FLOW_ERROR; - } - -done: - gst_buffer_unmap (buffer, &map); - gst_buffer_unref (buffer); - - return dec->flow_return; -} - -/* finds the packet type of the buffer - */ -static GstCmmlPacketType -gst_cmml_dec_parse_packet_type (GstCmmlDec * dec, gchar * data, gsize size) -{ - GstCmmlPacketType packet_type = GST_CMML_PACKET_UNKNOWN; - - if (size >= 8 && !memcmp (data, "CMML\0\0\0\0", 8)) { - packet_type = GST_CMML_PACKET_IDENT_HEADER; - } else if (size >= 5) { - if (!strncmp (data, "timestamp; - res = GST_FLOW_OK; - } else { - GST_WARNING_OBJECT (dec, "could not allocate buffer"); - res = GST_FLOW_ERROR; - } - - return res; -} - -/* parses the first CMML packet (the ident header) - */ -static void -gst_cmml_dec_parse_ident_header (GstCmmlDec * dec, guint8 * data, gsize size) -{ - /* the ident header has a fixed length */ - if (size != CMML_IDENT_HEADER_SIZE) { - GST_ELEMENT_ERROR (dec, STREAM, DECODE, - (NULL), ("wrong ident header size: %" G_GSIZE_FORMAT, size)); - dec->flow_return = GST_FLOW_ERROR; - - return; - } - - data += 8; - dec->major = GST_READ_UINT16_LE (data); - data += 2; - dec->minor = GST_READ_UINT16_LE (data); - data += 2; - dec->granulerate_n = GST_READ_UINT64_LE (data); - data += 8; - dec->granulerate_d = GST_READ_UINT64_LE (data); - data += 8; - dec->granuleshift = GST_READ_UINT8 (data); - - GST_INFO_OBJECT (dec, "bitstream initialized " - "(major: %" G_GINT16_FORMAT " minor: %" G_GINT16_FORMAT - " granulerate_n: %" G_GINT64_FORMAT " granulerate_d: %" G_GINT64_FORMAT - " granuleshift: %d)", - dec->major, dec->minor, - dec->granulerate_n, dec->granulerate_d, dec->granuleshift); - - dec->flow_return = GST_FLOW_OK; -} - -/* parses the first secondary header. - * the first secondary header contains the xml version, the doctype and the - * optional "cmml" processing instruction. - */ -static void -gst_cmml_dec_parse_first_header (GstCmmlDec * dec, guint8 * data, gsize size) -{ - gst_cmml_dec_parse_xml (dec, data, size); - - /* if there is a processing instruction, gst_cmml_dec_parse_preamble - * will be triggered. Otherwise we need to call it manually. - */ - if (dec->flow_return == GST_FLOW_OK && !dec->sent_root) { - guchar *preamble = (guchar *) g_strndup ((gchar *) data, size); - - gst_cmml_dec_parse_preamble (dec, preamble, (guchar *) ""); - g_free (preamble); - } -} - -/* feeds data into the cmml parser. - */ -static void -gst_cmml_dec_parse_xml (GstCmmlDec * dec, guchar * data, guint size) -{ - GError *err = NULL; - - if (!gst_cmml_parser_parse_chunk (dec->parser, (gchar *) data, size, &err)) { - GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("%s", err->message)); - g_error_free (err); - dec->flow_return = GST_FLOW_ERROR; - } -} - -static void -gst_cmml_dec_parse_preamble (GstCmmlDec * dec, guchar * preamble, - guchar * root_element) -{ - GstBuffer *buffer; - guchar *encoded_preamble; - - encoded_preamble = (guchar *) g_strconcat ((gchar *) preamble, - (gchar *) root_element, NULL); - - /* send the root element to the internal parser */ - gst_cmml_dec_parse_xml (dec, root_element, strlen ((gchar *) root_element)); - dec->sent_root = TRUE; - - /* push the root element */ - dec->flow_return = gst_cmml_dec_new_buffer (dec, - encoded_preamble, strlen ((gchar *) encoded_preamble), &buffer); - if (dec->flow_return == GST_FLOW_OK) { - dec->flow_return = gst_pad_push (dec->srcpad, buffer); - } - - if (dec->flow_return == GST_FLOW_OK) { - GST_INFO_OBJECT (dec, "preamble parsed"); - } - - g_free (encoded_preamble); - return; -} - -/* outputs the cmml head element and send TITLE and CMML_HEAD tags. - * This callback is registered with dec->parser. It is called when the - * head element is parsed. - */ -static void -gst_cmml_dec_parse_head (GstCmmlDec * dec, GstCmmlTagHead * head) -{ - GstTagList *tags; - GValue str_val = { 0 }, title_val = { - 0}; - guchar *head_str; - GstBuffer *buffer; - - GST_DEBUG_OBJECT (dec, "found CMML head (title: %s base: %s)", - head->title, head->base); - - /* FIXME: what's the point of all this GValue transform crack? */ - /* create the GST_TAG_TITLE tag */ - g_value_init (&str_val, G_TYPE_STRING); - g_value_init (&title_val, gst_tag_get_type (GST_TAG_TITLE)); - g_value_set_string (&str_val, (gchar *) head->title); - g_value_transform (&str_val, &title_val); - - tags = gst_tag_list_new_empty (); - gst_tag_list_add_values (tags, GST_TAG_MERGE_APPEND, - GST_TAG_TITLE, &title_val, NULL); - gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_CMML_HEAD, head, NULL); - gst_pad_push_event (dec->srcpad, gst_event_new_tag (tags)); - - g_value_unset (&str_val); - g_value_unset (&title_val); - - head_str = gst_cmml_parser_tag_head_to_string (dec->parser, head); - - dec->flow_return = gst_cmml_dec_new_buffer (dec, - head_str, strlen ((gchar *) head_str), &buffer); - g_free (head_str); - if (dec->flow_return == GST_FLOW_OK) - dec->flow_return = gst_pad_push (dec->srcpad, buffer); - if (dec->flow_return == GST_FLOW_NOT_LINKED) - dec->flow_return = GST_FLOW_OK; /* Ignore NOT_LINKED */ -} - -/* send a TAG_MESSAGE event for a clip */ -static void -gst_cmml_dec_send_clip_tag (GstCmmlDec * dec, GstCmmlTagClip * clip) -{ - GstTagList *tags; - - GST_DEBUG_OBJECT (dec, "sending clip tag %s", clip->id); - - tags = gst_tag_list_new (GST_TAG_CMML_CLIP, clip, NULL); - gst_pad_push_event (dec->srcpad, gst_event_new_tag (tags)); -} - -/* push the string representation of a clip */ -static void -gst_cmml_dec_push_clip (GstCmmlDec * dec, GstCmmlTagClip * clip) -{ - GstBuffer *buffer; - guchar *clip_str; - - GST_DEBUG_OBJECT (dec, "pushing clip %s", clip->id); - - clip_str = gst_cmml_parser_tag_clip_to_string (dec->parser, clip); - dec->flow_return = gst_cmml_dec_new_buffer (dec, - clip_str, strlen ((gchar *) clip_str), &buffer); - if (dec->flow_return == GST_FLOW_OK) - dec->flow_return = gst_pad_push (dec->srcpad, buffer); - if (dec->flow_return == GST_FLOW_NOT_LINKED) - dec->flow_return = GST_FLOW_OK; /* Ignore NOT_LINKED */ - - g_free (clip_str); -} - -/* decode a clip tag - * this callback is registered with dec->parser. It is called whenever a - * clip is parsed. - */ -static void -gst_cmml_dec_parse_clip (GstCmmlDec * dec, GstCmmlTagClip * clip) -{ - GstCmmlTagClip *prev_clip; - - dec->flow_return = GST_FLOW_OK; - - if (clip->empty) - GST_INFO_OBJECT (dec, "parsing empty clip"); - else - GST_INFO_OBJECT (dec, "parsing clip (id: %s)", clip->id); - - clip->start_time = dec->timestamp; - if (clip->start_time == GST_CLOCK_TIME_NONE) { - GST_ELEMENT_ERROR (dec, STREAM, DECODE, - (NULL), ("invalid clip start time")); - - dec->flow_return = GST_FLOW_ERROR; - return; - } - - /* get the last clip in the current track */ - prev_clip = gst_cmml_track_list_get_track_last_clip (dec->tracks, - (gchar *) clip->track); - if (prev_clip) { - /* output the previous clip */ - if (clip->empty) - /* the current clip marks the end of the previous one */ - prev_clip->end_time = clip->start_time; - - gst_cmml_dec_push_clip (dec, prev_clip); - } - - if (dec->wait_clip_end) { - /* now it's time to send the tag for the previous clip */ - if (prev_clip) { - prev_clip->end_time = clip->start_time; - gst_cmml_dec_send_clip_tag (dec, prev_clip); - } - } else if (!clip->empty) { - /* send the tag for the current clip */ - gst_cmml_dec_send_clip_tag (dec, clip); - } - - if (prev_clip) - gst_cmml_track_list_del_clip (dec->tracks, prev_clip); - - if (!clip->empty) - if (!gst_cmml_track_list_has_clip (dec->tracks, clip)) - gst_cmml_track_list_add_clip (dec->tracks, clip); -} - -gboolean -gst_cmml_dec_plugin_init (GstPlugin * plugin) -{ - if (!gst_element_register (plugin, "cmmldec", GST_RANK_PRIMARY, - GST_TYPE_CMML_DEC)) - return FALSE; - - GST_DEBUG_CATEGORY_INIT (cmmldec, "cmmldec", 0, - "annodex CMML decoding element"); - - return TRUE; -} diff --git a/ext/annodex/gstcmmldec.h b/ext/annodex/gstcmmldec.h deleted file mode 100644 index b7b302de80..0000000000 --- a/ext/annodex/gstcmmldec.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * gstcmmldec.h - GStreamer annodex CMML decoder - * Copyright (C) 2005 Alessandro Decina - * - * Authors: - * Alessandro Decina - * - * 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_CMML_DEC_H__ -#define __GST_CMML_DEC_H__ - -#include -#include - -#include "gstcmmlparser.h" - -/* GstCmmlDec */ -#define GST_TYPE_CMML_DEC (gst_cmml_dec_get_type()) -#define GST_CMML_DEC(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_CMML_DEC, GstCmmlDec)) -#define GST_CMML_DEC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_CMML_DEC, GstCmmlDecClass)) -#define GST_IS_CMML_DEC(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_CMML_DEC)) -#define GST_IS_CMML_DEC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_CMML_DEC)) -#define GST_CMML_DEC_GET_CLASS(klass) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_CMML_DEC, GstCmmlDecClass)) - -typedef struct _GstCmmlDec GstCmmlDec; -typedef struct _GstCmmlDecClass GstCmmlDecClass; -typedef enum _GstCmmlPacketType GstCmmlPacketType; - -enum _GstCmmlPacketType -{ - GST_CMML_PACKET_UNKNOWN, - GST_CMML_PACKET_IDENT_HEADER, - GST_CMML_PACKET_FIRST_HEADER, - GST_CMML_PACKET_SECOND_HEADER, - GST_CMML_PACKET_CLIP -}; - -struct _GstCmmlDec -{ - GstElement element; - - /* element part */ - GstPad *sinkpad; - GstPad *srcpad; - - /* bitstream part */ - gint16 major; /* bitstream version major */ - gint16 minor; /* bitstream version minor */ - gint64 granulerate_n; /* bitrstream granulerate numerator */ - gint64 granulerate_d; /* bitstream granulerate denominator */ - gint8 granuleshift; /* bitstreamgranuleshift */ - gint64 granulepos; /* bitstream granule position */ - GstClockTime timestamp; /* timestamp of the last buffer */ - - /* decoder part */ - GstCmmlParser *parser; /* cmml parser */ - gboolean sent_root; - GstFlowReturn flow_return; /* _chain return value */ - gboolean wait_clip_end; /* when TRUE, the GST_TAG_MESSAGE for a - * clip is sent when the next clip (or EOS) - * is found, so that the clip end-time is - * known. This is useful for pre-extracting - * the clips. - */ - GHashTable *tracks; -}; - -struct _GstCmmlDecClass -{ - GstElementClass parent_class; -}; - -GType gst_cmml_dec_get_type (void); - -gboolean gst_cmml_dec_plugin_init (GstPlugin * plugin); - -#endif /* __GST_CMML_DEC_H__ */ diff --git a/ext/annodex/gstcmmlenc.c b/ext/annodex/gstcmmlenc.c deleted file mode 100644 index d402c655aa..0000000000 --- a/ext/annodex/gstcmmlenc.c +++ /dev/null @@ -1,632 +0,0 @@ -/* - * gstcmmlenc.c - GStreamer CMML encoder - * Copyright (C) 2005 Alessandro Decina - * - * Authors: - * Alessandro Decina - * - * 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-cmmlenc - * @see_also: cmmldec, oggmux - * - * Cmmlenc encodes a CMML document into a CMML stream. CMML is - * an XML markup language for time-continuous data maintained by the Annodex Foundation. - * - * - * Example pipeline - * |[ - * gst-launch -v filesrc location=annotations.cmml ! cmmlenc ! oggmux name=mux ! filesink location=annotated.ogg - * ]| - * - */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "gstcmmlenc.h" -#include "gstannodex.h" - -GST_DEBUG_CATEGORY_STATIC (cmmlenc); -#define GST_CAT_DEFAULT cmmlenc - -#define CMML_IDENT_HEADER_SIZE 29 - -enum -{ - ARG_0, - GST_CMML_ENC_GRANULERATE_N, - GST_CMML_ENC_GRANULERATE_D, - GST_CMML_ENC_GRANULESHIFT -}; - -enum -{ - LAST_SIGNAL -}; - -static GstStaticPadTemplate gst_cmml_enc_src_factory = -GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("text/x-cmml, encoded = (boolean) true") - ); - -static GstStaticPadTemplate gst_cmml_enc_sink_factory = -GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("text/x-cmml, encoded = (boolean) false") - ); - -#define gst_cmml_enc_parent_class parent_class -G_DEFINE_TYPE (GstCmmlEnc, gst_cmml_enc, GST_TYPE_ELEMENT); - -static void gst_cmml_enc_get_property (GObject * object, guint property_id, - GValue * value, GParamSpec * pspec); -static void gst_cmml_enc_set_property (GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec); -static gboolean gst_cmml_enc_sink_event (GstPad * pad, GstObject * parent, - GstEvent * event); -static GstStateChangeReturn gst_cmml_enc_change_state (GstElement * element, - GstStateChange transition); -static GstFlowReturn gst_cmml_enc_chain (GstPad * pad, GstObject * parent, - GstBuffer * buffer); -static void gst_cmml_enc_parse_preamble (GstCmmlEnc * enc, guchar * preamble, - guchar * processing_instruction); -static void gst_cmml_enc_parse_end_tag (GstCmmlEnc * enc); -static void gst_cmml_enc_parse_tag_head (GstCmmlEnc * enc, - GstCmmlTagHead * head); -static void gst_cmml_enc_parse_tag_clip (GstCmmlEnc * enc, - GstCmmlTagClip * tag); -static GstFlowReturn gst_cmml_enc_new_buffer (GstCmmlEnc * enc, - guchar * data, gint size, GstBuffer ** buffer); -static GstFlowReturn gst_cmml_enc_push_clip (GstCmmlEnc * enc, - GstCmmlTagClip * clip, GstClockTime prev_clip_time); -static GstFlowReturn gst_cmml_enc_push (GstCmmlEnc * enc, GstBuffer * buffer); - -static void gst_cmml_enc_finalize (GObject * object); - -static void -gst_cmml_enc_class_init (GstCmmlEncClass * enc_class) -{ - GObjectClass *klass = G_OBJECT_CLASS (enc_class); - GstElementClass *element_class = GST_ELEMENT_CLASS (enc_class); - - klass->get_property = gst_cmml_enc_get_property; - klass->set_property = gst_cmml_enc_set_property; - klass->finalize = gst_cmml_enc_finalize; - - g_object_class_install_property (klass, GST_CMML_ENC_GRANULERATE_N, - g_param_spec_int64 ("granule-rate-numerator", - "Granulerate numerator", - "Granulerate numerator", - 0, G_MAXINT64, 1000, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (klass, GST_CMML_ENC_GRANULERATE_D, - g_param_spec_int64 ("granule-rate-denominator", - "Granulerate denominator", - "Granulerate denominator", - 0, G_MAXINT64, 1, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (klass, GST_CMML_ENC_GRANULESHIFT, - g_param_spec_uchar ("granule-shift", - "Granuleshift", - "The number of lower bits to use for partitioning a granule position", - 0, 64, 32, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - - element_class->change_state = gst_cmml_enc_change_state; - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_cmml_enc_sink_factory)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_cmml_enc_src_factory)); - gst_element_class_set_static_metadata (element_class, "CMML streams encoder", - "Codec/Encoder", - "Encodes CMML streams", "Alessandro Decina "); -} - -static void -gst_cmml_enc_init (GstCmmlEnc * enc) -{ - enc->sinkpad = - gst_pad_new_from_static_template (&gst_cmml_enc_sink_factory, "sink"); - gst_pad_set_chain_function (enc->sinkpad, gst_cmml_enc_chain); - gst_pad_set_event_function (enc->sinkpad, gst_cmml_enc_sink_event); - gst_element_add_pad (GST_ELEMENT (enc), enc->sinkpad); - - enc->srcpad = - gst_pad_new_from_static_template (&gst_cmml_enc_src_factory, "src"); - gst_element_add_pad (GST_ELEMENT (enc), enc->srcpad); - - enc->major = 3; - enc->minor = 0; -} - -static void -gst_cmml_enc_set_property (GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) -{ - GstCmmlEnc *enc = GST_CMML_ENC (object); - - switch (property_id) { - case GST_CMML_ENC_GRANULERATE_N: - /* XXX: may need to flush clips */ - enc->granulerate_n = g_value_get_int64 (value); - break; - case GST_CMML_ENC_GRANULERATE_D: - enc->granulerate_d = g_value_get_int64 (value); - break; - case GST_CMML_ENC_GRANULESHIFT: - enc->granuleshift = g_value_get_uchar (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - -static void -gst_cmml_enc_get_property (GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) -{ - GstCmmlEnc *enc = GST_CMML_ENC (object); - - switch (property_id) { - case GST_CMML_ENC_GRANULERATE_N: - g_value_set_int64 (value, enc->granulerate_n); - break; - case GST_CMML_ENC_GRANULERATE_D: - g_value_set_int64 (value, enc->granulerate_d); - break; - case GST_CMML_ENC_GRANULESHIFT: - g_value_set_uchar (value, enc->granuleshift); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - -static void -gst_cmml_enc_finalize (GObject * object) -{ - GstCmmlEnc *enc = GST_CMML_ENC (object); - - if (enc->tracks) { - gst_cmml_track_list_destroy (enc->tracks); - enc->tracks = NULL; - } - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static GstStateChangeReturn -gst_cmml_enc_change_state (GstElement * element, GstStateChange transition) -{ - GstCmmlEnc *enc = GST_CMML_ENC (element); - GstStateChangeReturn res; - - switch (transition) { - case GST_STATE_CHANGE_READY_TO_PAUSED: - enc->parser = gst_cmml_parser_new (GST_CMML_PARSER_ENCODE); - enc->parser->user_data = enc; - enc->parser->preamble_callback = - (GstCmmlParserPreambleCallback) gst_cmml_enc_parse_preamble; - enc->parser->head_callback = - (GstCmmlParserHeadCallback) gst_cmml_enc_parse_tag_head; - enc->parser->clip_callback = - (GstCmmlParserClipCallback) gst_cmml_enc_parse_tag_clip; - enc->parser->cmml_end_callback = - (GstCmmlParserCmmlEndCallback) gst_cmml_enc_parse_end_tag; - enc->tracks = gst_cmml_track_list_new (); - enc->sent_headers = FALSE; - enc->sent_eos = FALSE; - enc->flow_return = GST_FLOW_OK; - break; - default: - break; - } - - res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PAUSED_TO_READY: - { - gst_cmml_track_list_destroy (enc->tracks); - enc->tracks = NULL; - g_free (enc->preamble); - enc->preamble = NULL; - gst_cmml_parser_free (enc->parser); - break; - } - default: - break; - } - - return res; -} - -static gboolean -gst_cmml_enc_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) -{ - GstCmmlEnc *enc = GST_CMML_ENC (parent); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_EOS: - { - if (!enc->sent_eos) - gst_cmml_enc_parse_end_tag (enc); - - break; - } - default: - break; - } - - return gst_pad_event_default (pad, parent, event); -} - -static GstFlowReturn -gst_cmml_enc_new_buffer (GstCmmlEnc * enc, - guchar * data, gint size, GstBuffer ** buffer) -{ - GstFlowReturn res; - - *buffer = gst_buffer_new_allocate (NULL, size, NULL); - if (*buffer != NULL) { - if (data) - gst_buffer_fill (*buffer, 0, data, size); - res = GST_FLOW_OK; - } else { - GST_WARNING_OBJECT (enc, "could not allocate buffer"); - res = GST_FLOW_ERROR; - } - - return res; -} - -static GstCaps * -gst_cmml_enc_set_header_on_caps (GstCmmlEnc * enc, GstCaps * caps, - GstBuffer * ident, GstBuffer * preamble, GstBuffer * head) -{ - GValue array = { 0 }; - GValue value = { 0 }; - GstStructure *structure; - GstBuffer *buffer; - - caps = gst_caps_make_writable (caps); - structure = gst_caps_get_structure (caps, 0); - - g_value_init (&array, GST_TYPE_ARRAY); - g_value_init (&value, GST_TYPE_BUFFER); - - /* Make copies of header buffers to avoid circular references */ - buffer = gst_buffer_copy (ident); - gst_value_set_buffer (&value, buffer); - gst_value_array_append_value (&array, &value); - gst_buffer_unref (buffer); - - buffer = gst_buffer_copy (preamble); - gst_value_set_buffer (&value, buffer); - gst_value_array_append_value (&array, &value); - gst_buffer_unref (buffer); - - buffer = gst_buffer_copy (head); - gst_value_set_buffer (&value, buffer); - gst_value_array_append_value (&array, &value); - gst_buffer_unref (buffer); - - GST_BUFFER_FLAG_SET (ident, GST_BUFFER_FLAG_HEADER); - GST_BUFFER_FLAG_SET (preamble, GST_BUFFER_FLAG_HEADER); - GST_BUFFER_FLAG_SET (head, GST_BUFFER_FLAG_HEADER); - - gst_structure_set_value (structure, "streamheader", &array); - - g_value_unset (&value); - g_value_unset (&array); - - return caps; -} - -/* create a CMML ident header buffer - */ -static GstFlowReturn -gst_cmml_enc_new_ident_header (GstCmmlEnc * enc, GstBuffer ** buffer) -{ - guint8 ident_header[CMML_IDENT_HEADER_SIZE]; - guint8 *wptr = ident_header; - - memcpy (wptr, "CMML\0\0\0\0", 8); - wptr += 8; - GST_WRITE_UINT16_LE (wptr, enc->major); - wptr += 2; - GST_WRITE_UINT16_LE (wptr, enc->minor); - wptr += 2; - GST_WRITE_UINT64_LE (wptr, enc->granulerate_n); - wptr += 8; - GST_WRITE_UINT64_LE (wptr, enc->granulerate_d); - wptr += 8; - *wptr = enc->granuleshift; - - return gst_cmml_enc_new_buffer (enc, - (guchar *) & ident_header, CMML_IDENT_HEADER_SIZE, buffer); -} - -/* parse the CMML preamble */ -static void -gst_cmml_enc_parse_preamble (GstCmmlEnc * enc, - guchar * preamble, guchar * processing_instruction) -{ - GST_INFO_OBJECT (enc, "parsing preamble"); - - /* save the preamble: it will be pushed when the head tag is found */ - enc->preamble = (guchar *) g_strconcat ((gchar *) preamble, - (gchar *) processing_instruction, NULL); -} - -/* parse the CMML end tag */ -static void -gst_cmml_enc_parse_end_tag (GstCmmlEnc * enc) -{ - GstBuffer *buffer; - - GST_INFO_OBJECT (enc, "parsing end tag"); - - /* push an empty buffer to signal EOS */ - enc->flow_return = gst_cmml_enc_new_buffer (enc, NULL, 0, &buffer); - if (enc->flow_return == GST_FLOW_OK) { - /* set granulepos 0 on EOS */ - GST_BUFFER_OFFSET_END (buffer) = 0; - enc->flow_return = gst_cmml_enc_push (enc, buffer); - enc->sent_eos = TRUE; - } - - return; -} - -/* encode the CMML head tag and push the CMML headers - */ -static void -gst_cmml_enc_parse_tag_head (GstCmmlEnc * enc, GstCmmlTagHead * head) -{ - GList *headers = NULL; - GList *walk; - guchar *head_string; - GstCaps *caps; - GstBuffer *ident_buf, *preamble_buf, *head_buf; - GstBuffer *buffer; - - if (enc->preamble == NULL) - goto flow_unexpected; - - GST_INFO_OBJECT (enc, "parsing head tag"); - - enc->flow_return = gst_cmml_enc_new_ident_header (enc, &ident_buf); - if (enc->flow_return != GST_FLOW_OK) - goto alloc_error; - headers = g_list_append (headers, ident_buf); - - enc->flow_return = gst_cmml_enc_new_buffer (enc, - enc->preamble, strlen ((gchar *) enc->preamble), &preamble_buf); - if (enc->flow_return != GST_FLOW_OK) - goto alloc_error; - headers = g_list_append (headers, preamble_buf); - - head_string = gst_cmml_parser_tag_head_to_string (enc->parser, head); - enc->flow_return = gst_cmml_enc_new_buffer (enc, - head_string, strlen ((gchar *) head_string), &head_buf); - g_free (head_string); - if (enc->flow_return != GST_FLOW_OK) - goto alloc_error; - headers = g_list_append (headers, head_buf); - - caps = gst_pad_query_caps (enc->srcpad, NULL); - caps = gst_cmml_enc_set_header_on_caps (enc, caps, - ident_buf, preamble_buf, head_buf); - gst_pad_set_caps (enc->srcpad, caps); - gst_caps_unref (caps); - - while (headers) { - buffer = GST_BUFFER (headers->data); - /* set granulepos 0 on headers */ - GST_BUFFER_OFFSET_END (buffer) = 0; - - enc->flow_return = gst_cmml_enc_push (enc, buffer); - headers = g_list_delete_link (headers, headers); - - if (enc->flow_return != GST_FLOW_OK) - goto push_error; - } - - enc->sent_headers = TRUE; - return; - -flow_unexpected: - GST_ELEMENT_ERROR (enc, STREAM, ENCODE, - (NULL), ("got head tag before preamble")); - enc->flow_return = GST_FLOW_ERROR; - return; -push_error: - /* fallthrough */ -alloc_error: - for (walk = headers; walk; walk = walk->next) - gst_buffer_unref (GST_BUFFER (walk->data)); - g_list_free (headers); - return; -} - -/* encode a CMML clip tag - * remove the start and end attributes (GstCmmlParser does this itself) and - * push the tag with the timestamp of its start attribute. If the tag has the - * end attribute, create a new empty clip and encode it. - */ -static void -gst_cmml_enc_parse_tag_clip (GstCmmlEnc * enc, GstCmmlTagClip * clip) -{ - GstCmmlTagClip *prev_clip; - GstClockTime prev_clip_time = GST_CLOCK_TIME_NONE; - - /* this can happen if there's a programming error (eg user forgets to set - * the start-time property) or if one of the gst_cmml_clock_time_from_* - * overflows in GstCmmlParser */ - if (clip->start_time == GST_CLOCK_TIME_NONE) { - GST_ELEMENT_ERROR (enc, STREAM, ENCODE, - (NULL), ("invalid start time for clip (%s)", clip->id)); - enc->flow_return = GST_FLOW_ERROR; - - return; - } - - /* get the previous clip's start time to encode the current granulepos */ - prev_clip = gst_cmml_track_list_get_track_last_clip (enc->tracks, - (gchar *) clip->track); - if (prev_clip) { - prev_clip_time = prev_clip->start_time; - if (prev_clip_time > clip->start_time) { - GST_ELEMENT_ERROR (enc, STREAM, ENCODE, - (NULL), ("previous clip start time > current clip (%s) start time", - clip->id)); - enc->flow_return = GST_FLOW_ERROR; - return; - } - - /* we don't need the prev clip anymore */ - gst_cmml_track_list_del_clip (enc->tracks, prev_clip); - } - - /* add the current clip to the tracklist */ - gst_cmml_track_list_add_clip (enc->tracks, clip); - - enc->flow_return = gst_cmml_enc_push_clip (enc, clip, prev_clip_time); -} - -static GstFlowReturn -gst_cmml_enc_push_clip (GstCmmlEnc * enc, GstCmmlTagClip * clip, - GstClockTime prev_clip_time) -{ - GstFlowReturn res; - GstBuffer *buffer; - gchar *clip_string; - gint64 granulepos; - - /* encode the clip */ - clip_string = - (gchar *) gst_cmml_parser_tag_clip_to_string (enc->parser, clip); - - res = gst_cmml_enc_new_buffer (enc, - (guchar *) clip_string, strlen (clip_string), &buffer); - g_free (clip_string); - if (res != GST_FLOW_OK) - goto done; - - GST_INFO_OBJECT (enc, "encoding clip" - "(start-time: %" GST_TIME_FORMAT " end-time: %" GST_TIME_FORMAT, - GST_TIME_ARGS (clip->start_time), GST_TIME_ARGS (clip->end_time)); - - /* set the granulepos */ - granulepos = gst_cmml_clock_time_to_granule (prev_clip_time, clip->start_time, - enc->granulerate_n, enc->granulerate_d, enc->granuleshift); - if (granulepos == -1) { - gst_buffer_unref (buffer); - goto granule_overflow; - } - - GST_BUFFER_OFFSET (buffer) = clip->start_time; - GST_BUFFER_OFFSET_END (buffer) = granulepos; - GST_BUFFER_TIMESTAMP (buffer) = clip->start_time; - - res = gst_cmml_enc_push (enc, buffer); - if (res != GST_FLOW_OK) - goto done; - - if (clip->end_time != GST_CLOCK_TIME_NONE) { - /* create a new empty clip for the same cmml track starting at end_time - */ - GObject *end_clip = g_object_new (GST_TYPE_CMML_TAG_CLIP, - "start-time", clip->end_time, "track", clip->track, NULL); - - /* encode the empty end clip */ - gst_cmml_enc_push_clip (enc, GST_CMML_TAG_CLIP (end_clip), - clip->start_time); - g_object_unref (end_clip); - } -done: - return res; - -granule_overflow: - GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL), ("granulepos overflow")); - return GST_FLOW_ERROR; -} - -static GstFlowReturn -gst_cmml_enc_push (GstCmmlEnc * enc, GstBuffer * buffer) -{ - GstFlowReturn res; - - res = gst_pad_push (enc->srcpad, buffer); - if (res != GST_FLOW_OK) - GST_WARNING_OBJECT (enc, "push returned: %s", gst_flow_get_name (res)); - - return res; -} - -static GstFlowReturn -gst_cmml_enc_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) -{ - GError *err = NULL; - GstCmmlEnc *enc = GST_CMML_ENC (parent); - GstMapInfo map; - - /* the CMML handlers registered with enc->parser will override this when - * encoding/pushing the buffers downstream - */ - enc->flow_return = GST_FLOW_OK; - - gst_buffer_map (buffer, &map, GST_MAP_READ); - - if (!gst_cmml_parser_parse_chunk (enc->parser, (gchar *) map.data, map.size, - &err)) { - GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL), ("%s", err->message)); - g_error_free (err); - enc->flow_return = GST_FLOW_ERROR; - } - - gst_buffer_unmap (buffer, &map); - gst_buffer_unref (buffer); - return enc->flow_return; -} - -gboolean -gst_cmml_enc_plugin_init (GstPlugin * plugin) -{ - if (!gst_element_register (plugin, "cmmlenc", GST_RANK_NONE, - GST_TYPE_CMML_ENC)) - return FALSE; - - GST_DEBUG_CATEGORY_INIT (cmmlenc, "cmmlenc", 0, - "annodex cmml decoding element"); - - return TRUE; -} diff --git a/ext/annodex/gstcmmlenc.h b/ext/annodex/gstcmmlenc.h deleted file mode 100644 index 4f28e4c537..0000000000 --- a/ext/annodex/gstcmmlenc.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * gstcmmlenc.h - GStreamer CMML encoder - * Copyright (C) 2005 Alessandro Decina - * - * Authors: - * Alessandro Decina - * - * 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_CMML_ENC_H__ -#define __GST_CMML_ENC_H__ - -#define GST_TYPE_CMML_ENC (gst_cmml_enc_get_type()) -#define GST_CMML_ENC(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_CMML_ENC, GstCmmlEnc)) -#define GST_CMML_ENC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_CMML_ENC, GstCmmlEncClass)) -#define GST_IS_CMML_ENC(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_CMML_ENC)) -#define GST_IS_CMML_ENC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_CMML_ENC)) -#define GST_CMML_ENC_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_CMML_ENC, GstCmmlEncClass)) - -#include -#include - -#include "gstcmmlparser.h" -#include "gstcmmlutils.h" - -typedef struct _GstCmmlEnc GstCmmlEnc; -typedef struct _GstCmmlEncClass GstCmmlEncClass; - -struct _GstCmmlEnc -{ - GstElement element; - - GstPad *sinkpad; - GstPad *srcpad; - - gint16 major; - gint16 minor; - gint64 granulerate_n; - gint64 granulerate_d; - gint8 granuleshift; - - GstCmmlParser *parser; - gboolean streaming; - GHashTable *tracks; - GstFlowReturn flow_return; - guchar *preamble; - gboolean sent_headers; - gboolean sent_eos; -}; - -struct _GstCmmlEncClass -{ - GstElementClass parent_class; -}; - -GType gst_cmml_enc_get_type (void); - -gboolean gst_cmml_enc_plugin_init (GstPlugin * plugin); - -#endif /* __GST_CMML_ENC_H__ */ diff --git a/ext/annodex/gstcmmlparser.c b/ext/annodex/gstcmmlparser.c deleted file mode 100644 index b76cf4a0bd..0000000000 --- a/ext/annodex/gstcmmlparser.c +++ /dev/null @@ -1,652 +0,0 @@ -/* - * gstcmmlparser.c - GStreamer CMML document parser - * Copyright (C) 2005 Alessandro Decina - * - * Authors: - * Alessandro Decina - * - * 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. - */ - -/* FIXME 0.11: suppress warnings for deprecated API such as GValueArray - * with newer GLib versions (>= 2.31.0) */ -#define GLIB_DISABLE_DEPRECATION_WARNINGS - -#include -#include -#include - -#include "gstcmmlparser.h" -#include "gstannodex.h" -#include "gstcmmlutils.h" - -GST_DEBUG_CATEGORY_STATIC (cmmlparser); -#define GST_CAT_DEFAULT cmmlparser - -static void gst_cmml_parser_generic_error (void *ctx, const char *msg, ...); -static xmlNodePtr gst_cmml_parser_new_node (GstCmmlParser * parser, - const gchar * name, ...); -static void -gst_cmml_parser_parse_start_element_ns (xmlParserCtxt * ctxt, - const xmlChar * name, const xmlChar * prefix, const xmlChar * URI, - int nb_preferences, const xmlChar ** namespaces, - int nb_attributes, int nb_defaulted, const xmlChar ** attributes); -static void gst_cmml_parser_parse_end_element_ns (xmlParserCtxt * ctxt, - const xmlChar * name, const xmlChar * prefix, const xmlChar * URI); -static void gst_cmml_parser_parse_processing_instruction (xmlParserCtxtPtr ctxt, - const xmlChar * target, const xmlChar * data); -static void gst_cmml_parser_meta_to_string (GstCmmlParser * parser, - xmlNodePtr parent, GValueArray * meta); - -/* initialize the parser */ -void -gst_cmml_parser_init (void) -{ - GST_DEBUG_CATEGORY_INIT (cmmlparser, "cmmlparser", 0, "annodex CMML parser"); - - xmlGenericError = gst_cmml_parser_generic_error; -} - -/* create a new CMML parser - */ -GstCmmlParser * -gst_cmml_parser_new (GstCmmlParserMode mode) -{ - GstCmmlParser *parser = g_malloc (sizeof (GstCmmlParser)); - - parser->mode = mode; - parser->context = xmlCreatePushParserCtxt (NULL, NULL, - NULL, 0, "cmml-bitstream"); - xmlCtxtUseOptions (parser->context, XML_PARSE_NONET | XML_PARSE_NOERROR); - parser->context->_private = parser; - parser->context->sax->startElementNs = - (startElementNsSAX2Func) gst_cmml_parser_parse_start_element_ns; - parser->context->sax->endElementNs = - (endElementNsSAX2Func) gst_cmml_parser_parse_end_element_ns; - parser->context->sax->processingInstruction = (processingInstructionSAXFunc) - gst_cmml_parser_parse_processing_instruction; - parser->preamble_callback = NULL; - parser->cmml_end_callback = NULL; - parser->stream_callback = NULL; - parser->head_callback = NULL; - parser->clip_callback = NULL; - parser->user_data = NULL; - - return parser; -} - -/* free a CMML parser instance - */ -void -gst_cmml_parser_free (GstCmmlParser * parser) -{ - if (parser) { - xmlFreeDoc (parser->context->myDoc); - xmlFreeParserCtxt (parser->context); - g_free (parser); - } -} - -/* parse an xml chunk - * - * returns false if the xml is invalid - */ -gboolean -gst_cmml_parser_parse_chunk (GstCmmlParser * parser, - const gchar * data, guint size, GError ** err) -{ - gint xmlres; - - xmlres = xmlParseChunk (parser->context, data, size, 0); - if (xmlres != XML_ERR_OK) { - xmlErrorPtr xml_error = xmlCtxtGetLastError (parser->context); - - GST_DEBUG ("Error occurred decoding chunk %s", data); - g_set_error (err, - GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED, "%s", xml_error->message); - return FALSE; - } - - return TRUE; -} - -/* convert an xmlNodePtr to a string - */ -static guchar * -gst_cmml_parser_node_to_string (GstCmmlParser * parser, xmlNodePtr node) -{ - xmlBufferPtr xml_buffer; - xmlDocPtr doc; - guchar *str; - - if (parser) - doc = parser->context->myDoc; - else - doc = NULL; - - xml_buffer = xmlBufferCreate (); - xmlNodeDump (xml_buffer, doc, node, 0, 0); - str = xmlStrndup (xml_buffer->content, xml_buffer->use); - xmlBufferFree (xml_buffer); - - return str; -} - -guchar * -gst_cmml_parser_tag_stream_to_string (GstCmmlParser * parser, - GstCmmlTagStream * stream) -{ - xmlNodePtr node; - xmlNodePtr import; - guchar *ret; - - node = gst_cmml_parser_new_node (parser, "stream", NULL); - if (stream->timebase) - xmlSetProp (node, (xmlChar *) "timebase", stream->timebase); - - if (stream->utc) - xmlSetProp (node, (xmlChar *) "utc", stream->utc); - - if (stream->imports) { - gint i; - GValue *val; - - for (i = 0; i < stream->imports->n_values; ++i) { - val = g_value_array_get_nth (stream->imports, i); - import = gst_cmml_parser_new_node (parser, "import", - "src", g_value_get_string (val), NULL); - xmlAddChild (node, import); - } - } - - ret = gst_cmml_parser_node_to_string (parser, node); - - xmlUnlinkNode (node); - xmlFreeNode (node); - - return ret; -} - -/* convert a GstCmmlTagHead to its string representation - */ -guchar * -gst_cmml_parser_tag_head_to_string (GstCmmlParser * parser, - GstCmmlTagHead * head) -{ - xmlNodePtr node; - xmlNodePtr tmp; - guchar *ret; - - node = gst_cmml_parser_new_node (parser, "head", NULL); - if (head->title) { - tmp = gst_cmml_parser_new_node (parser, "title", NULL); - xmlNodeSetContent (tmp, head->title); - xmlAddChild (node, tmp); - } - - if (head->base) { - tmp = gst_cmml_parser_new_node (parser, "base", "uri", head->base, NULL); - xmlAddChild (node, tmp); - } - - if (head->meta) - gst_cmml_parser_meta_to_string (parser, node, head->meta); - - ret = gst_cmml_parser_node_to_string (parser, node); - - xmlUnlinkNode (node); - xmlFreeNode (node); - - return ret; -} - -/* convert a GstCmmlTagClip to its string representation - */ -guchar * -gst_cmml_parser_tag_clip_to_string (GstCmmlParser * parser, - GstCmmlTagClip * clip) -{ - xmlNodePtr node; - xmlNodePtr tmp; - guchar *ret; - - node = gst_cmml_parser_new_node (parser, "clip", - "id", clip->id, "track", clip->track, NULL); - /* add the anchor element */ - if (clip->anchor_href) { - tmp = gst_cmml_parser_new_node (parser, "a", - "href", clip->anchor_href, NULL); - if (clip->anchor_text) - xmlNodeSetContent (tmp, clip->anchor_text); - - xmlAddChild (node, tmp); - } - /* add the img element */ - if (clip->img_src) { - tmp = gst_cmml_parser_new_node (parser, "img", - "src", clip->img_src, "alt", clip->img_alt, NULL); - - xmlAddChild (node, tmp); - } - /* add the desc element */ - if (clip->desc_text) { - tmp = gst_cmml_parser_new_node (parser, "desc", NULL); - xmlNodeSetContent (tmp, clip->desc_text); - - xmlAddChild (node, tmp); - } - /* add the meta elements */ - if (clip->meta) - gst_cmml_parser_meta_to_string (parser, node, clip->meta); - - if (parser->mode == GST_CMML_PARSER_DECODE) { - gchar *time_str; - - time_str = gst_cmml_clock_time_to_npt (clip->start_time); - if (time_str == NULL) - goto fail; - - xmlSetProp (node, (xmlChar *) "start", (xmlChar *) time_str); - g_free (time_str); - - if (clip->end_time != GST_CLOCK_TIME_NONE) { - time_str = gst_cmml_clock_time_to_npt (clip->end_time); - if (time_str == NULL) - goto fail; - - xmlSetProp (node, (xmlChar *) "end", (xmlChar *) time_str); - g_free (time_str); - } - } - - ret = gst_cmml_parser_node_to_string (parser, node); - - xmlUnlinkNode (node); - xmlFreeNode (node); - - return ret; -fail: - xmlUnlinkNode (node); - xmlFreeNode (node); - return NULL; -} - -guchar * -gst_cmml_parser_tag_object_to_string (GstCmmlParser * parser, GObject * tag) -{ - guchar *tag_string = NULL; - GType tag_type = G_OBJECT_TYPE (tag); - - if (tag_type == GST_TYPE_CMML_TAG_STREAM) - tag_string = gst_cmml_parser_tag_stream_to_string (parser, - GST_CMML_TAG_STREAM (tag)); - else if (tag_type == GST_TYPE_CMML_TAG_HEAD) - tag_string = gst_cmml_parser_tag_head_to_string (parser, - GST_CMML_TAG_HEAD (tag)); - else if (tag_type == GST_TYPE_CMML_TAG_CLIP) - tag_string = gst_cmml_parser_tag_clip_to_string (parser, - GST_CMML_TAG_CLIP (tag)); - else - g_warning ("could not convert object to cmml"); - - return tag_string; -} - -/*** private section ***/ - -/* create a new node - * - * helper to create a node and set its attributes - */ -static xmlNodePtr -gst_cmml_parser_new_node (GstCmmlParser * parser, const gchar * name, ...) -{ - va_list args; - xmlNodePtr node; - xmlChar *prop_name, *prop_value; - - node = xmlNewNode (NULL, (xmlChar *) name); - - va_start (args, name); - - prop_name = va_arg (args, xmlChar *); - while (prop_name != NULL) { - prop_value = va_arg (args, xmlChar *); - if (prop_value != NULL) - xmlSetProp (node, prop_name, prop_value); - - prop_name = va_arg (args, xmlChar *); - } - va_end (args); - - return node; -} - -/* get the last node of the stream - * - * returns the last node at depth 1 (if any) or the root node - */ -static xmlNodePtr -gst_cmml_parser_get_last_element (GstCmmlParser * parser) -{ - xmlNodePtr node; - - node = xmlDocGetRootElement (parser->context->myDoc); - if (!node) { - g_warning ("no last cmml element"); - return NULL; - } - - if (node->children) - node = xmlGetLastChild (node); - - return node; -} - -static void -gst_cmml_parser_parse_preamble (GstCmmlParser * parser, - const guchar * attributes) -{ - gchar *preamble; - gchar *element; - const gchar *version; - const gchar *encoding; - const gchar *standalone; - xmlDocPtr doc; - - doc = parser->context->myDoc; - - version = doc->version ? (gchar *) doc->version : "1.0"; - encoding = doc->encoding ? (gchar *) doc->encoding : "UTF-8"; - standalone = doc->standalone ? "yes" : "no"; - - preamble = g_strdup_printf ("\n" - "\n", version, encoding, standalone); - - if (attributes == NULL) - attributes = (guchar *) ""; - - if (parser->mode == GST_CMML_PARSER_ENCODE) - element = g_strdup_printf ("", attributes); - else - element = g_strdup_printf ("", attributes); - - parser->preamble_callback (parser->user_data, - (guchar *) preamble, (guchar *) element); - - g_free (preamble); - g_free (element); -} - -/* parse the cmml stream tag */ -static void -gst_cmml_parser_parse_stream (GstCmmlParser * parser, xmlNodePtr stream) -{ - GstCmmlTagStream *stream_tag; - GValue str_val = { 0 }; - xmlNodePtr walk; - guchar *timebase; - - g_value_init (&str_val, G_TYPE_STRING); - - /* read the timebase and utc attributes */ - timebase = xmlGetProp (stream, (xmlChar *) "timebase"); - if (timebase == NULL) - timebase = (guchar *) g_strdup ("0"); - - stream_tag = g_object_new (GST_TYPE_CMML_TAG_STREAM, - "timebase", timebase, NULL); - g_free (timebase); - - stream_tag->utc = xmlGetProp (stream, (xmlChar *) "utc"); - - /* walk the children nodes */ - for (walk = stream->children; walk; walk = walk->next) { - /* for every import tag add its src attribute to stream_tag->imports */ - if (!xmlStrcmp (walk->name, (xmlChar *) "import")) { - g_value_take_string (&str_val, - (gchar *) xmlGetProp (walk, (xmlChar *) "src")); - - if (stream_tag->imports == NULL) - stream_tag->imports = g_value_array_new (0); - - g_value_array_append (stream_tag->imports, &str_val); - } - } - g_value_unset (&str_val); - - parser->stream_callback (parser->user_data, stream_tag); - g_object_unref (stream_tag); -} - -/* parse the cmml head tag */ -static void -gst_cmml_parser_parse_head (GstCmmlParser * parser, xmlNodePtr head) -{ - GstCmmlTagHead *head_tag; - xmlNodePtr walk; - GValue str_val = { 0 }; - - head_tag = g_object_new (GST_TYPE_CMML_TAG_HEAD, NULL); - - g_value_init (&str_val, G_TYPE_STRING); - - /* Parse the content of the node and setup the GST_TAG_CMML_HEAD tag. - * Create a GST_TAG_TITLE when we find the title element. - */ - for (walk = head->children; walk; walk = walk->next) { - if (!xmlStrcmp (walk->name, (xmlChar *) "title")) { - head_tag->title = xmlNodeGetContent (walk); - } else if (!xmlStrcmp (walk->name, (xmlChar *) "base")) { - head_tag->base = xmlGetProp (walk, (xmlChar *) "uri"); - } else if (!xmlStrcmp (walk->name, (xmlChar *) "meta")) { - if (head_tag->meta == NULL) - head_tag->meta = g_value_array_new (0); - /* add a pair name, content to the meta value array */ - g_value_take_string (&str_val, - (gchar *) xmlGetProp (walk, (xmlChar *) "name")); - g_value_array_append (head_tag->meta, &str_val); - g_value_take_string (&str_val, - (gchar *) xmlGetProp (walk, (xmlChar *) "content")); - g_value_array_append (head_tag->meta, &str_val); - } - } - g_value_unset (&str_val); - - parser->head_callback (parser->user_data, head_tag); - g_object_unref (head_tag); -} - -/* parse a cmml clip tag */ -static void -gst_cmml_parser_parse_clip (GstCmmlParser * parser, xmlNodePtr clip) -{ - GstCmmlTagClip *clip_tag; - GValue str_val = { 0 }; - guchar *id, *track, *start, *end; - xmlNodePtr walk; - GstClockTime start_time = GST_CLOCK_TIME_NONE; - GstClockTime end_time = GST_CLOCK_TIME_NONE; - - start = xmlGetProp (clip, (xmlChar *) "start"); - if (parser->mode == GST_CMML_PARSER_ENCODE && start == NULL) - /* XXX: validate the document */ - return; - - id = xmlGetProp (clip, (xmlChar *) "id"); - track = xmlGetProp (clip, (xmlChar *) "track"); - end = xmlGetProp (clip, (xmlChar *) "end"); - - if (track == NULL) - track = (guchar *) g_strdup ("default"); - - if (start) { - if (!strncmp ((gchar *) start, "smpte", 5)) - start_time = gst_cmml_clock_time_from_smpte ((gchar *) start); - else - start_time = gst_cmml_clock_time_from_npt ((gchar *) start); - } - - if (end) { - if (!strncmp ((gchar *) end, "smpte", 5)) - start_time = gst_cmml_clock_time_from_smpte ((gchar *) end); - else - end_time = gst_cmml_clock_time_from_npt ((gchar *) end); - } - - clip_tag = g_object_new (GST_TYPE_CMML_TAG_CLIP, "id", id, - "track", track, "start-time", start_time, "end-time", end_time, NULL); - - g_free (id); - g_free (track); - g_free (start); - g_free (end); - - g_value_init (&str_val, G_TYPE_STRING); - - /* parse the children */ - for (walk = clip->children; walk; walk = walk->next) { - /* the clip is not empty */ - clip_tag->empty = FALSE; - - if (!xmlStrcmp (walk->name, (xmlChar *) "a")) { - clip_tag->anchor_href = xmlGetProp (walk, (xmlChar *) "href"); - clip_tag->anchor_text = xmlNodeGetContent (walk); - } else if (!xmlStrcmp (walk->name, (xmlChar *) "img")) { - clip_tag->img_src = xmlGetProp (walk, (xmlChar *) "src"); - clip_tag->img_alt = xmlGetProp (walk, (xmlChar *) "alt"); - } else if (!xmlStrcmp (walk->name, (xmlChar *) "desc")) { - clip_tag->desc_text = xmlNodeGetContent (walk); - } else if (!xmlStrcmp (walk->name, (xmlChar *) "meta")) { - if (clip_tag->meta == NULL) - clip_tag->meta = g_value_array_new (0); - /* add a pair name, content to the meta value array */ - g_value_take_string (&str_val, - (char *) xmlGetProp (walk, (xmlChar *) "name")); - g_value_array_append (clip_tag->meta, &str_val); - g_value_take_string (&str_val, - (char *) xmlGetProp (walk, (xmlChar *) "content")); - g_value_array_append (clip_tag->meta, &str_val); - } - } - g_value_unset (&str_val); - - parser->clip_callback (parser->user_data, clip_tag); - g_object_unref (clip_tag); -} - -void -gst_cmml_parser_meta_to_string (GstCmmlParser * parser, - xmlNodePtr parent, GValueArray * array) -{ - gint i; - xmlNodePtr node; - GValue *name, *content; - - for (i = 0; i < array->n_values - 1; i += 2) { - name = g_value_array_get_nth (array, i); - content = g_value_array_get_nth (array, i + 1); - node = gst_cmml_parser_new_node (parser, "meta", - "name", g_value_get_string (name), - "content", g_value_get_string (content), NULL); - xmlAddChild (parent, node); - } -} - -static void -gst_cmml_parser_generic_error (void *ctx, const char *msg, ...) -{ -#ifndef GST_DISABLE_GST_DEBUG - va_list varargs; - - va_start (varargs, msg); - gst_debug_log_valist (GST_CAT_DEFAULT, GST_LEVEL_WARNING, - "", "", 0, NULL, msg, varargs); - va_end (varargs); -#endif /* GST_DISABLE_GST_DEBUG */ -} - -/* sax handler called when an element start tag is found - * this is used to parse the cmml start tag - */ -static void -gst_cmml_parser_parse_start_element_ns (xmlParserCtxt * ctxt, - const xmlChar * name, const xmlChar * prefix, const xmlChar * URI, - int nb_preferences, const xmlChar ** namespaces, - int nb_attributes, int nb_defaulted, const xmlChar ** attributes) -{ - GstCmmlParser *parser = (GstCmmlParser *) ctxt->_private; - - xmlSAX2StartElementNs (ctxt, name, prefix, URI, nb_preferences, namespaces, - nb_attributes, nb_defaulted, attributes); - - if (parser->mode == GST_CMML_PARSER_ENCODE) - if (!xmlStrcmp (name, (xmlChar *) "cmml")) - if (parser->preamble_callback) - /* FIXME: parse attributes */ - gst_cmml_parser_parse_preamble (parser, NULL); -} - -/* sax processing instruction handler - * used to parse the cmml processing instruction - */ -static void -gst_cmml_parser_parse_processing_instruction (xmlParserCtxtPtr ctxt, - const xmlChar * target, const xmlChar * data) -{ - GstCmmlParser *parser = (GstCmmlParser *) ctxt->_private; - - xmlSAX2ProcessingInstruction (ctxt, target, data); - - if (parser->mode == GST_CMML_PARSER_DECODE) - if (!xmlStrcmp (target, (xmlChar *) "cmml")) - if (parser->preamble_callback) - gst_cmml_parser_parse_preamble (parser, data); -} - -/* sax handler called when an xml end tag is found - * used to parse the stream, head and clip nodes - */ -static void -gst_cmml_parser_parse_end_element_ns (xmlParserCtxt * ctxt, - const xmlChar * name, const xmlChar * prefix, const xmlChar * URI) -{ - xmlNodePtr node; - GstCmmlParser *parser = (GstCmmlParser *) ctxt->_private; - - xmlSAX2EndElementNs (ctxt, name, prefix, URI); - - if (!xmlStrcmp (name, (xmlChar *) "clip")) { - if (parser->clip_callback) { - node = gst_cmml_parser_get_last_element (parser); - gst_cmml_parser_parse_clip (parser, node); - } - } else if (!xmlStrcmp (name, (xmlChar *) "cmml")) { - if (parser->cmml_end_callback) - parser->cmml_end_callback (parser->user_data); - } else if (!xmlStrcmp (name, (xmlChar *) "stream")) { - if (parser->stream_callback) { - node = gst_cmml_parser_get_last_element (parser); - gst_cmml_parser_parse_stream (parser, node); - } - } else if (!xmlStrcmp (name, (xmlChar *) "head")) { - if (parser->head_callback) { - node = gst_cmml_parser_get_last_element (parser); - gst_cmml_parser_parse_head (parser, node); - } - } -} diff --git a/ext/annodex/gstcmmlparser.h b/ext/annodex/gstcmmlparser.h deleted file mode 100644 index 89c2bffa7b..0000000000 --- a/ext/annodex/gstcmmlparser.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * gstcmmlparser.h - GStreamer CMML document parser - * Copyright (C) 2005 Alessandro Decina - * - * Authors: - * Alessandro Decina - * - * 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_CMML_PARSER_H__ -#define __GST_CMML_PARSER_H__ - -#include -#include - -#include "gstcmmltag.h" - -typedef struct _GstCmmlParser GstCmmlParser; -typedef enum _GstCmmlParserMode GstCmmlParserMode; - -typedef void (*GstCmmlParserPreambleCallback) (void *user_data, - const guchar * xml_preamble, const guchar * cmml_attrs); - -typedef void (*GstCmmlParserCmmlEndCallback) (void *user_data); - -typedef void (*GstCmmlParserStreamCallback) (void *user_data, - GstCmmlTagStream * stream); - -typedef void (*GstCmmlParserHeadCallback) (void *user_data, - GstCmmlTagHead * head); - -typedef void (*GstCmmlParserClipCallback) (void *user_data, - GstCmmlTagClip * clip); - -enum _GstCmmlParserMode -{ - GST_CMML_PARSER_ENCODE, - GST_CMML_PARSER_DECODE -}; - -struct _GstCmmlParser -{ - GstCmmlParserMode mode; - - xmlParserCtxtPtr context; - - const gchar *preamble; - guint preamble_size; - - void *user_data; - GstCmmlParserPreambleCallback preamble_callback; - GstCmmlParserStreamCallback stream_callback; - GstCmmlParserCmmlEndCallback cmml_end_callback; - GstCmmlParserHeadCallback head_callback; - GstCmmlParserClipCallback clip_callback; -}; - -void gst_cmml_parser_init (void); - -GstCmmlParser *gst_cmml_parser_new (GstCmmlParserMode mode); -void gst_cmml_parser_free (GstCmmlParser * parser); - -gboolean gst_cmml_parser_parse_chunk (GstCmmlParser * parser, - const gchar * data, guint size, GError ** error); - -guchar *gst_cmml_parser_tag_stream_to_string (GstCmmlParser * parser, - GstCmmlTagStream * stream); - -guchar *gst_cmml_parser_tag_head_to_string (GstCmmlParser * parser, - GstCmmlTagHead * head); - -guchar *gst_cmml_parser_tag_clip_to_string (GstCmmlParser * parser, - GstCmmlTagClip * clip); - -guchar *gst_cmml_parser_tag_object_to_string (GstCmmlParser * parser, - GObject * tag); - -#endif /* __GST_CMML_PARSER_H__ */ diff --git a/ext/annodex/gstcmmltag.c b/ext/annodex/gstcmmltag.c deleted file mode 100644 index 8b2a1893e0..0000000000 --- a/ext/annodex/gstcmmltag.c +++ /dev/null @@ -1,583 +0,0 @@ -/* - * gstcmmltags.c - GStreamer CMML tag support - * Copyright (C) 2005 Alessandro Decina - * - * Authors: - * Alessandro Decina - * - * 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. - */ - -/* FIXME 0.11: suppress warnings for deprecated API such as GValueArray - * with newer GLib versions (>= 2.31.0) */ -#define GLIB_DISABLE_DEPRECATION_WARNINGS - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "gstcmmlparser.h" -#include "gstcmmltag.h" -#include "gstannodex.h" - -enum -{ - ARG_0, - GST_CMML_TAG_STREAM_TIMEBASE, - GST_CMML_TAG_STREAM_UTC, - GST_CMML_TAG_STREAM_IMPORTS, - GST_CMML_TAG_HEAD_TITLE, - GST_CMML_TAG_HEAD_BASE, - GST_CMML_TAG_HEAD_META, - GST_CMML_TAG_CLIP_EMPTY, - GST_CMML_TAG_CLIP_ID, - GST_CMML_TAG_CLIP_TRACK, - GST_CMML_TAG_CLIP_START_TIME, - GST_CMML_TAG_CLIP_END_TIME, - GST_CMML_TAG_CLIP_ANCHOR_HREF, - GST_CMML_TAG_CLIP_ANCHOR_TEXT, - GST_CMML_TAG_CLIP_IMG_SRC, - GST_CMML_TAG_CLIP_IMG_ALT, - GST_CMML_TAG_CLIP_DESC_TEXT, - GST_CMML_TAG_CLIP_META, -}; - -G_DEFINE_TYPE (GstCmmlTagStream, gst_cmml_tag_stream, G_TYPE_OBJECT); -static void gst_cmml_tag_stream_finalize (GObject * object); -static void gst_cmml_tag_stream_set_property (GObject * object, - guint property_id, const GValue * value, GParamSpec * pspec); -static void gst_cmml_tag_stream_get_property (GObject * object, - guint property_id, GValue * value, GParamSpec * pspec); -static void gst_cmml_tag_stream_value_from_string_value (const GValue * src, - GValue * dest); - -G_DEFINE_TYPE (GstCmmlTagHead, gst_cmml_tag_head, G_TYPE_OBJECT); -static void gst_cmml_tag_head_finalize (GObject * object); -static void gst_cmml_tag_head_set_property (GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec); -static void gst_cmml_tag_head_get_property (GObject * object, guint property_id, - GValue * value, GParamSpec * pspec); -static void gst_cmml_tag_head_value_from_string_value (const GValue * src, - GValue * dest); - -G_DEFINE_TYPE (GstCmmlTagClip, gst_cmml_tag_clip, G_TYPE_OBJECT); -static void gst_cmml_tag_clip_finalize (GObject * object); -static void gst_cmml_tag_clip_set_property (GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec); -static void gst_cmml_tag_clip_get_property (GObject * object, guint property_id, - GValue * value, GParamSpec * pspec); - -static void gst_cmml_tag_clip_value_from_string_value (const GValue * src, - GValue * dest); - -static void set_object_on_value (GObject * object, GValue * dest); - -static const gchar default_preamble[] = - ""; - -/* Stream tag */ -static void -gst_cmml_tag_stream_class_init (GstCmmlTagStreamClass * stream_class) -{ - GObjectClass *klass = G_OBJECT_CLASS (stream_class); - - klass->set_property = gst_cmml_tag_stream_set_property; - klass->get_property = gst_cmml_tag_stream_get_property; - klass->finalize = gst_cmml_tag_stream_finalize; - - g_object_class_install_property (klass, GST_CMML_TAG_STREAM_TIMEBASE, - g_param_spec_string ("base-time", - "Base time", - "Playback time (in seconds) of the first data packet", - "0", G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (klass, GST_CMML_TAG_STREAM_UTC, - g_param_spec_string ("calendar-base-time", - "Calendar base time", - "Date and wall-clock time (expressed as UTC time in the format " - "YYYYMMDDTHHMMSS.sssZ) associated with the base-time", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (klass, GST_CMML_TAG_STREAM_IMPORTS, - g_param_spec_value_array ("input-streams", - "Input streams", - "List of input streams that compose this bitstream", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - - g_value_register_transform_func (G_TYPE_STRING, GST_TYPE_CMML_TAG_STREAM, - gst_cmml_tag_stream_value_from_string_value); -} - -static void -gst_cmml_tag_stream_init (GstCmmlTagStream * stream) -{ -} - -static void -gst_cmml_tag_stream_finalize (GObject * object) -{ - GstCmmlTagStream *stream = GST_CMML_TAG_STREAM (object); - - g_free (stream->timebase); - g_free (stream->utc); - if (stream->imports) - g_value_array_free (stream->imports); - - if (G_OBJECT_CLASS (gst_cmml_tag_stream_parent_class)->finalize) - G_OBJECT_CLASS (gst_cmml_tag_stream_parent_class)->finalize (object); -} - -static void -gst_cmml_tag_stream_set_property (GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) -{ - GstCmmlTagStream *stream = GST_CMML_TAG_STREAM (object); - - switch (property_id) { - case GST_CMML_TAG_STREAM_TIMEBASE: - g_free (stream->timebase); - stream->timebase = (guchar *) g_value_dup_string (value); - break; - case GST_CMML_TAG_STREAM_UTC: - g_free (stream->utc); - stream->utc = (guchar *) g_value_dup_string (value); - break; - case GST_CMML_TAG_STREAM_IMPORTS: - { - GValueArray *va = g_value_get_boxed (value); - - if (stream->imports) - g_value_array_free (stream->imports); - stream->imports = va != NULL ? g_value_array_copy (va) : NULL; - break; - } - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - - -static void -gst_cmml_tag_stream_value_from_string_value (const GValue * src, GValue * dest) -{ - GstCmmlParser *parser; - const gchar *str; - guint size; - - parser = gst_cmml_parser_new (GST_CMML_PARSER_DECODE); - parser->user_data = dest; - parser->stream_callback = (GstCmmlParserStreamCallback) set_object_on_value; - gst_cmml_parser_parse_chunk (parser, - default_preamble, strlen (default_preamble), NULL); - - str = g_value_get_string (src); - size = strlen (str); - gst_cmml_parser_parse_chunk (parser, str, size, NULL); - - gst_cmml_parser_free (parser); -} - -static void -gst_cmml_tag_stream_get_property (GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) -{ - GstCmmlTagStream *stream = GST_CMML_TAG_STREAM (object); - - switch (property_id) { - case GST_CMML_TAG_STREAM_TIMEBASE: - g_value_set_string (value, (gchar *) stream->timebase); - break; - case GST_CMML_TAG_STREAM_UTC: - g_value_set_string (value, (gchar *) stream->utc); - break; - case GST_CMML_TAG_STREAM_IMPORTS: - g_value_set_boxed (value, stream->imports); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - -/* Head tag */ -static void -gst_cmml_tag_head_class_init (GstCmmlTagHeadClass * head_class) -{ - GObjectClass *klass = G_OBJECT_CLASS (head_class); - - klass->set_property = gst_cmml_tag_head_set_property; - klass->get_property = gst_cmml_tag_head_get_property; - klass->finalize = gst_cmml_tag_head_finalize; - - g_object_class_install_property (klass, GST_CMML_TAG_HEAD_TITLE, - g_param_spec_string ("title", - "Title", - "Title of the bitstream", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (klass, GST_CMML_TAG_HEAD_BASE, - g_param_spec_string ("base-uri", - "Base URI", - "Base URI of the bitstream. All relative URIs are relative to this", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (klass, GST_CMML_TAG_HEAD_META, - g_param_spec_value_array ("meta", - "Meta annotations", - "Meta annotations for the complete Annodex bitstream", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - - g_value_register_transform_func (G_TYPE_STRING, GST_TYPE_CMML_TAG_HEAD, - gst_cmml_tag_head_value_from_string_value); -} - -static void -gst_cmml_tag_head_init (GstCmmlTagHead * head) -{ -} - -static void -gst_cmml_tag_head_finalize (GObject * object) -{ - GstCmmlTagHead *head = GST_CMML_TAG_HEAD (object); - - g_free (head->title); - g_free (head->base); - if (head->meta) - g_value_array_free (head->meta); - - if (G_OBJECT_CLASS (gst_cmml_tag_head_parent_class)->finalize) - G_OBJECT_CLASS (gst_cmml_tag_head_parent_class)->finalize (object); -} - -static void -gst_cmml_tag_head_set_property (GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) -{ - GstCmmlTagHead *head = GST_CMML_TAG_HEAD (object); - - switch (property_id) { - case GST_CMML_TAG_HEAD_TITLE: - g_free (head->title); - head->title = (guchar *) g_value_dup_string (value); - break; - case GST_CMML_TAG_HEAD_BASE: - g_free (head->base); - head->base = (guchar *) g_value_dup_string (value); - break; - case GST_CMML_TAG_HEAD_META: - { - GValueArray *va = g_value_get_boxed (value); - - if (head->meta) - g_value_array_free (head->meta); - head->meta = va != NULL ? g_value_array_copy (va) : NULL; - break; - } - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - -static void -gst_cmml_tag_head_get_property (GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) -{ - GstCmmlTagHead *head = GST_CMML_TAG_HEAD (object); - - switch (property_id) { - case GST_CMML_TAG_HEAD_TITLE: - g_value_set_string (value, (gchar *) head->title); - break; - case GST_CMML_TAG_HEAD_BASE: - g_value_set_string (value, (gchar *) head->base); - break; - case GST_CMML_TAG_HEAD_META: - g_value_set_boxed (value, head->meta); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - -static void -gst_cmml_tag_head_value_from_string_value (const GValue * src, GValue * dest) -{ - GstCmmlParser *parser; - const gchar *str; - guint size; - - parser = gst_cmml_parser_new (GST_CMML_PARSER_DECODE); - parser->user_data = dest; - parser->head_callback = (GstCmmlParserHeadCallback) set_object_on_value; - gst_cmml_parser_parse_chunk (parser, - default_preamble, strlen (default_preamble), NULL); - - str = g_value_get_string (src); - size = strlen (str); - gst_cmml_parser_parse_chunk (parser, str, size, NULL); - - gst_cmml_parser_free (parser); -} - -/* Clip tag */ -static void -gst_cmml_tag_clip_class_init (GstCmmlTagClipClass * clip_class) -{ - GObjectClass *klass = G_OBJECT_CLASS (clip_class); - - klass->set_property = gst_cmml_tag_clip_set_property; - klass->get_property = gst_cmml_tag_clip_get_property; - klass->finalize = gst_cmml_tag_clip_finalize; - - g_object_class_install_property (klass, GST_CMML_TAG_CLIP_EMPTY, - g_param_spec_boolean ("empty", - "Empty clip flag", - "An empty clip only marks the end of the previous clip", - TRUE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (klass, GST_CMML_TAG_CLIP_ID, - g_param_spec_string ("id", - "Clip id", - "Id of the clip", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (klass, GST_CMML_TAG_CLIP_TRACK, - g_param_spec_string ("track", - "Track number", - "The track this clip belongs to", - "default", - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (klass, GST_CMML_TAG_CLIP_START_TIME, - g_param_spec_uint64 ("start-time", - "Start time", - "The start time (in seconds) of the clip", - 0, G_MAXUINT64, GST_CLOCK_TIME_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (klass, GST_CMML_TAG_CLIP_END_TIME, - g_param_spec_uint64 ("end-time", - "End time", - "The end time (in seconds) of the clip (only set if extract-mode=true)", - 0, G_MAXUINT64, GST_CLOCK_TIME_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (klass, GST_CMML_TAG_CLIP_ANCHOR_HREF, - g_param_spec_string ("anchor-uri", - "Anchor URI", - "The location of a Web resource closely connected to the clip", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (klass, GST_CMML_TAG_CLIP_ANCHOR_TEXT, - g_param_spec_string ("anchor-text", - "Anchor text", - "A short description of the resource pointed by anchor-uri", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (klass, GST_CMML_TAG_CLIP_IMG_SRC, - g_param_spec_string ("img-uri", - "Image URI", - "The URI of a representative image for the clip", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (klass, GST_CMML_TAG_CLIP_IMG_ALT, - g_param_spec_string ("img-alt", - "Image alternative text", - "Alternative text to be displayed instead of the image " - "specified in img-uri", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (klass, GST_CMML_TAG_CLIP_DESC_TEXT, - g_param_spec_string ("description", - "Description", - "A textual description of the content of the clip", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (klass, GST_CMML_TAG_CLIP_META, - g_param_spec_value_array ("meta", - "Meta annotations", - "Meta annotations for the clip", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - - g_value_register_transform_func (G_TYPE_STRING, GST_TYPE_CMML_TAG_CLIP, - gst_cmml_tag_clip_value_from_string_value); -} - -static void -gst_cmml_tag_clip_init (GstCmmlTagClip * clip) -{ -} - -static void -gst_cmml_tag_clip_finalize (GObject * object) -{ - GstCmmlTagClip *clip = GST_CMML_TAG_CLIP (object); - - g_free (clip->id); - g_free (clip->track); - g_free (clip->anchor_href); - g_free (clip->anchor_text); - g_free (clip->img_src); - g_free (clip->img_alt); - g_free (clip->desc_text); - if (clip->meta) - g_value_array_free (clip->meta); - - if (G_OBJECT_CLASS (gst_cmml_tag_clip_parent_class)->finalize) - G_OBJECT_CLASS (gst_cmml_tag_clip_parent_class)->finalize (object); -} - -static void -gst_cmml_tag_clip_set_property (GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) -{ - GstCmmlTagClip *clip = GST_CMML_TAG_CLIP (object); - - switch (property_id) { - case GST_CMML_TAG_CLIP_EMPTY: - clip->empty = g_value_get_boolean (value); - break; - case GST_CMML_TAG_CLIP_ID: - g_free (clip->id); - clip->id = (guchar *) g_value_dup_string (value); - break; - case GST_CMML_TAG_CLIP_TRACK: - g_free (clip->track); - clip->track = (guchar *) g_value_dup_string (value); - break; - case GST_CMML_TAG_CLIP_START_TIME: - clip->start_time = g_value_get_uint64 (value); - break; - case GST_CMML_TAG_CLIP_END_TIME: - clip->end_time = g_value_get_uint64 (value); - break; - case GST_CMML_TAG_CLIP_ANCHOR_HREF: - g_free (clip->anchor_href); - clip->anchor_href = (guchar *) g_value_dup_string (value); - break; - case GST_CMML_TAG_CLIP_ANCHOR_TEXT: - g_free (clip->anchor_text); - clip->anchor_text = (guchar *) g_value_dup_string (value); - break; - case GST_CMML_TAG_CLIP_IMG_SRC: - g_free (clip->img_src); - clip->img_src = (guchar *) g_value_dup_string (value); - break; - case GST_CMML_TAG_CLIP_IMG_ALT: - g_free (clip->img_alt); - clip->img_alt = (guchar *) g_value_dup_string (value); - break; - case GST_CMML_TAG_CLIP_DESC_TEXT: - g_free (clip->desc_text); - clip->desc_text = (guchar *) g_value_dup_string (value); - break; - case GST_CMML_TAG_CLIP_META: - { - GValueArray *va = (GValueArray *) g_value_get_boxed (value); - - if (clip->meta) - g_value_array_free (clip->meta); - - clip->meta = va != NULL ? g_value_array_copy (va) : NULL; - - break; - } - } -} - -static void -gst_cmml_tag_clip_get_property (GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) -{ - GstCmmlTagClip *clip = GST_CMML_TAG_CLIP (object); - - switch (property_id) { - case GST_CMML_TAG_CLIP_EMPTY: - g_value_set_boolean (value, clip->empty); - break; - case GST_CMML_TAG_CLIP_ID: - g_value_set_string (value, (gchar *) clip->id); - break; - case GST_CMML_TAG_CLIP_TRACK: - g_value_set_string (value, (gchar *) clip->track); - break; - case GST_CMML_TAG_CLIP_START_TIME: - g_value_set_uint64 (value, clip->start_time); - break; - case GST_CMML_TAG_CLIP_END_TIME: - g_value_set_uint64 (value, clip->end_time); - break; - case GST_CMML_TAG_CLIP_ANCHOR_HREF: - g_value_set_string (value, (gchar *) clip->anchor_href); - break; - case GST_CMML_TAG_CLIP_ANCHOR_TEXT: - g_value_set_string (value, (gchar *) clip->anchor_text); - break; - case GST_CMML_TAG_CLIP_IMG_SRC: - g_value_set_string (value, (gchar *) clip->img_src); - break; - case GST_CMML_TAG_CLIP_IMG_ALT: - g_value_set_string (value, (gchar *) clip->img_alt); - break; - case GST_CMML_TAG_CLIP_DESC_TEXT: - g_value_set_string (value, (gchar *) clip->desc_text); - break; - case GST_CMML_TAG_CLIP_META: - g_value_set_boxed (value, clip->meta); - break; - } -} - -static void -gst_cmml_tag_clip_value_from_string_value (const GValue * src, GValue * dest) -{ - GstCmmlParser *parser; - const gchar *str; - guint size; - - parser = gst_cmml_parser_new (GST_CMML_PARSER_DECODE); - parser->user_data = dest; - parser->clip_callback = (GstCmmlParserClipCallback) set_object_on_value; - - gst_cmml_parser_parse_chunk (parser, default_preamble, - strlen (default_preamble), NULL); - - str = g_value_get_string (src); - size = strlen (str); - - gst_cmml_parser_parse_chunk (parser, str, size, NULL); - - gst_cmml_parser_free (parser); -} - -static void -set_object_on_value (GObject * tag, GValue * dest) -{ - g_value_take_object (dest, tag); -} diff --git a/ext/annodex/gstcmmltag.h b/ext/annodex/gstcmmltag.h deleted file mode 100644 index e8c9bbb878..0000000000 --- a/ext/annodex/gstcmmltag.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * gstcmmltag.h - GStreamer annodex CMML tag support - * Copyright (C) 2005 Alessandro Decina - * - * Authors: - * Alessandro Decina - * - * 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_CMML_TAG_H__ -#define __GST_CMML_TAG_H__ - -#include - -/* GstCmmlTagStream */ -#define GST_TYPE_CMML_TAG_STREAM (gst_cmml_tag_stream_get_type ()) -#define GST_CMML_TAG_STREAM(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_TYPE_CMML_TAG_STREAM, GstCmmlTagStream)) -#define GST_CMML_TAG_STREAM_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_TYPE_CMML_TAG_STREAM, GstCmmlTagStreamClass)) -#define GST_CMML_TAG_STREAM_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_TYPE_CMML_TAG_STREAM, GstCmmlTagStreamClass)) - -/* GstCmmlTagHead */ -#define GST_TYPE_CMML_TAG_HEAD (gst_cmml_tag_head_get_type ()) -#define GST_CMML_TAG_HEAD(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_CMML_TAG_HEAD, GstCmmlTagHead)) -#define GST_CMML_TAG_HEAD_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_CMML_TAG_HEAD, GstCmmlTagHeadClass)) -#define GST_CMML_TAG_HEAD_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_TYPE_CMML_TAG_HEAD, GstCmmlTagHeadClass)) - -/* GstCmmlTagClip */ -#define GST_TYPE_CMML_TAG_CLIP (gst_cmml_tag_clip_get_type ()) -#define GST_CMML_TAG_CLIP(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_CMML_TAG_CLIP, GstCmmlTagClip)) -#define GST_CMML_TAG_CLIP_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_CMML_TAG_CLIP, GstCmmlTagClipClass)) -#define GST_CMML_TAG_CLIP_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_TYPE_CMML_TAG_CLIP, GstCmmlTagClipClass)) - -typedef struct _GstCmmlTagStream GstCmmlTagStream; -typedef struct _GstCmmlTagStreamClass GstCmmlTagStreamClass; -typedef struct _GstCmmlTagHead GstCmmlTagHead; -typedef struct _GstCmmlTagHeadClass GstCmmlTagHeadClass; -typedef struct _GstCmmlTagClip GstCmmlTagClip; -typedef struct _GstCmmlTagClipClass GstCmmlTagClipClass; - -struct _GstCmmlTagStream { - GObject object; - - guchar *timebase; - guchar *utc; - - GValueArray *imports; -}; - -struct _GstCmmlTagStreamClass { - GObjectClass parent_class; -}; - -struct _GstCmmlTagHead { - GObject object; - - guchar *title; /* title of the media */ - guchar *base; - GValueArray *meta; /* metadata attached to the media. - * The elements are positioned in key-value - * pairs ie (key, content, key2, content2, - * ...) - */ -}; - -struct _GstCmmlTagHeadClass { - GObjectClass parent_class; -}; - -struct _GstCmmlTagClip { - GObject object; - - gboolean empty; /* empty flag. An empty clip marks the - * end of the previous clip. - */ - - guchar *id; /* clip id */ - guchar *track; /* clip track */ - - GstClockTime start_time; /* clip start time */ - GstClockTime end_time; /* clip end time */ - - guchar *anchor_href; /* anchor href URI */ - guchar *anchor_text; /* anchor text */ - - guchar *img_src; /* image URI */ - guchar *img_alt; /* image alternative text */ - - guchar *desc_text; /* clip description */ - - GValueArray *meta; /* metadata attached to the clip - * The elements are positioned in key-value - * pairs ie (key, content, key2, content2, - * ...) - */ -}; - -struct _GstCmmlTagClipClass { - GObjectClass parent_class; -}; - -GType gst_cmml_tag_stream_get_type (void); -GType gst_cmml_tag_head_get_type (void); -GType gst_cmml_tag_clip_get_type (void); - -#endif /* __GST_CMML_TAG_H__ */ diff --git a/ext/annodex/gstcmmlutils.c b/ext/annodex/gstcmmlutils.c deleted file mode 100644 index a66b3f0642..0000000000 --- a/ext/annodex/gstcmmlutils.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - * gstcmmlutils.c - GStreamer CMML utility functions - * Copyright (C) 2005 Alessandro Decina - * - * Authors: - * Alessandro Decina - * - * 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 "gstcmmlutils.h" - -#include -#include -#include - -typedef struct -{ - GList *clips; - gpointer user_data; -} GstCmmlTrack; - -GstClockTime -gst_cmml_clock_time_from_npt (const gchar * time) -{ - GstClockTime res; - gint fields; - gint hours = 0; - gint minutes = 0; - gint seconds = 0; - gint mseconds = 0; - GstClockTime hours_t = 0, seconds_t = 0; - - if (!strncmp (time, "npt:", 4)) - time += 4; - - /* parse npt-hhmmss */ - fields = sscanf (time, "%d:%d:%d.%d", &hours, &minutes, &seconds, &mseconds); - if (fields == 4) { - if (hours < 0 || (guint) minutes > 59 || (guint) seconds > 59) - goto bad_input; - - hours_t = gst_util_uint64_scale (hours, GST_SECOND * 3600, 1); - if (hours_t == G_MAXUINT64) - goto overflow; - - seconds_t = seconds * GST_SECOND; - } else { - guint64 u64seconds; - - /* parse npt-sec */ - hours_t = 0; - minutes = 0; - fields = sscanf (time, "%" G_GUINT64_FORMAT ".%d", &u64seconds, &mseconds); - if (seconds < 0) - goto bad_input; - - seconds_t = gst_util_uint64_scale_int (u64seconds, GST_SECOND, 1); - if (seconds_t == G_MAXUINT64) - goto overflow; - } - - if ((guint) mseconds > 999) - goto bad_input; - - res = (minutes * 60) * GST_SECOND + mseconds * GST_MSECOND; - if (G_MAXUINT64 - hours_t - seconds_t < res) - goto overflow; - - res += hours_t + seconds_t; - - return res; - -bad_input: -overflow: - return GST_CLOCK_TIME_NONE; -} - -GstClockTime -gst_cmml_clock_time_from_smpte (const gchar * time) -{ - GstClockTime res; - GstClockTime hours_t; - gint hours, minutes, seconds; - gdouble framerate; - gfloat frames; - gint fields; - - if (!strncmp (time, "smpte-24:", 9)) { - framerate = 24.0; - time += 9; - } else if (!strncmp (time, "smpte-24-drop:", 14)) { - framerate = 23.976; - time += 14; - } else if (!strncmp (time, "smpte-25:", 9)) { - framerate = 25.0; - time += 9; - } else if (!strncmp (time, "smpte-30:", 9)) { - framerate = 30.0; - time += 9; - } else if (!strncmp (time, "smpte-30-drop:", 14)) { - framerate = 29.976; - time += 14; - } else if (!strncmp (time, "smpte-50:", 9)) { - framerate = 50.0; - time += 9; - } else if (!strncmp (time, "smpte-60:", 9)) { - framerate = 60.0; - time += 9; - } else if (!strncmp (time, "smpte-60-drop:", 14)) { - framerate = 59.94; - time += 14; - } else { - return GST_CLOCK_TIME_NONE; - } - - fields = sscanf (time, "%d:%d:%d:%f", &hours, &minutes, &seconds, &frames); - if (fields == 4) { - if (hours < 0 || (guint) minutes > 59 || (guint) seconds > 59 || - frames < 0 || frames > ceil (framerate)) { - res = GST_CLOCK_TIME_NONE; - } else { - hours_t = gst_util_uint64_scale (hours, GST_SECOND * 3600, 1); - if (hours_t == G_MAXUINT64) - goto overflow; - - res = ((minutes * 60) + seconds + (frames / framerate)) - * GST_SECOND; - if (G_MAXUINT64 - hours_t < res) - goto overflow; - - res = hours_t + res; - } - } else { - res = GST_CLOCK_TIME_NONE; - } - - return res; -overflow: - return GST_CLOCK_TIME_NONE; -} - -gchar * -gst_cmml_clock_time_to_npt (const GstClockTime time) -{ - guint seconds, hours, minutes, mseconds; - gchar *res; - - g_return_val_if_fail (time != GST_CLOCK_TIME_NONE, NULL); - - hours = time / (GST_SECOND * 3600); - minutes = (time / ((GST_SECOND * 60)) % 60); - seconds = (time / GST_SECOND) % 60; - mseconds = (time % GST_SECOND) / GST_MSECOND; - - if (mseconds < 100) - mseconds *= 10; - - res = g_strdup_printf ("%u:%02u:%02u.%03u", - hours, minutes, seconds, mseconds); - - return res; -} - -gint64 -gst_cmml_clock_time_to_granule (GstClockTime prev_time, - GstClockTime current_time, gint64 granulerate_n, gint64 granulerate_d, - guint8 granuleshift) -{ - guint64 keyindex, keyoffset, granulepos, maxoffset; - gint64 granulerate; - - g_return_val_if_fail (granulerate_d != 0, -1); - g_return_val_if_fail (granuleshift > 0, -1); - g_return_val_if_fail (granuleshift <= 64, -1); - - if (prev_time == GST_CLOCK_TIME_NONE) - prev_time = 0; - - if (prev_time > current_time) - return -1; - - /* GST_SECOND / (granulerate_n / granulerate_d) */ - granulerate = gst_util_uint64_scale (GST_SECOND, - granulerate_d, granulerate_n); - - prev_time = prev_time / granulerate; - - /* granuleshift == 64 should be a << 0 shift, which is defined */ - maxoffset = ((guint64) 1 << (64 - granuleshift)) - 1; - if (prev_time > maxoffset) - /* we need more than 64 - granuleshift bits to encode prev_time */ - goto overflow; - - keyindex = prev_time << granuleshift; - - keyoffset = (current_time / granulerate) - prev_time; - /* make sure we don't shift to the limits of the types as this is undefined. */ - if (granuleshift == 64) - maxoffset = G_MAXUINT64; - else - maxoffset = ((guint64) 1 << granuleshift) - 1; - - if (keyoffset > maxoffset) - /* we need more than granuleshift bits to encode prev_time - current_time */ - goto overflow; - - granulepos = keyindex + keyoffset; - - return granulepos; - -overflow: - return -1; -} - -/* track list */ -GHashTable * -gst_cmml_track_list_new (void) -{ - return g_hash_table_new (g_str_hash, g_str_equal); -} - -static gboolean -gst_cmml_track_list_destroy_track (gchar * key, - GstCmmlTrack * track, gpointer user_data) -{ - GList *walk; - - for (walk = track->clips; walk; walk = g_list_next (walk)) - g_object_unref (G_OBJECT (walk->data)); - - g_free (key); - g_list_free (track->clips); - g_free (track); - - return TRUE; -} - -void -gst_cmml_track_list_destroy (GHashTable * tracks) -{ - g_hash_table_foreach_remove (tracks, - (GHRFunc) gst_cmml_track_list_destroy_track, NULL); - g_hash_table_destroy (tracks); -} - -static gint -gst_cmml_track_list_compare_clips (GstCmmlTagClip * a, GstCmmlTagClip * b) -{ - if (a->start_time < b->start_time) - return -1; - - return 1; -} - -void -gst_cmml_track_list_add_clip (GHashTable * tracks, GstCmmlTagClip * clip) -{ - gpointer key, value; - GstCmmlTrack *track; - gchar *track_name; - - g_return_if_fail (clip->track != NULL); - - if (g_hash_table_lookup_extended (tracks, clip->track, &key, &value)) { - track_name = (gchar *) key; - track = (GstCmmlTrack *) value; - } else { - track_name = g_strdup ((gchar *) clip->track); - track = g_new0 (GstCmmlTrack, 1); - g_hash_table_insert (tracks, track_name, track); - } - - /* add clip to the tracklist */ - track->clips = g_list_insert_sorted (track->clips, g_object_ref (clip), - (GCompareFunc) gst_cmml_track_list_compare_clips); -} - -gboolean -gst_cmml_track_list_del_clip (GHashTable * tracks, GstCmmlTagClip * clip) -{ - GstCmmlTrack *track; - GList *link; - gboolean res = FALSE; - - g_return_val_if_fail (clip->track != NULL, FALSE); - - track = g_hash_table_lookup (tracks, clip->track); - if (track) { - link = g_list_find (track->clips, clip); - if (link) { - g_object_unref (G_OBJECT (link->data)); - track->clips = g_list_delete_link (track->clips, link); - res = TRUE; - } - } - - return res; -} - -gboolean -gst_cmml_track_list_has_clip (GHashTable * tracks, GstCmmlTagClip * clip) -{ - GstCmmlTrack *track; - GList *walk; - GstCmmlTagClip *tmp; - gboolean res = FALSE; - - track = g_hash_table_lookup (tracks, (gchar *) clip->track); - if (track) { - for (walk = track->clips; walk; walk = g_list_next (walk)) { - tmp = GST_CMML_TAG_CLIP (walk->data); - if (tmp->start_time == clip->start_time) { - res = TRUE; - break; - } - } - } - - return res; -} - -static gboolean -gst_cmml_track_list_merge_track (gchar * track_name, - GstCmmlTrack * track, GList ** list) -{ - GList *walk; - GstCmmlTagClip *cur; - - for (walk = track->clips; walk; walk = g_list_next (walk)) { - cur = GST_CMML_TAG_CLIP (walk->data); - *list = g_list_insert_sorted (*list, cur, - (GCompareFunc) gst_cmml_track_list_compare_clips); - } - - return TRUE; -} - -GList * -gst_cmml_track_list_get_track_clips (GHashTable * tracks, - const gchar * track_name) -{ - GstCmmlTrack *track; - - g_return_val_if_fail (track_name != NULL, NULL); - - track = g_hash_table_lookup (tracks, track_name); - return track ? track->clips : NULL; -} - -GList * -gst_cmml_track_list_get_clips (GHashTable * tracks) -{ - GList *list = NULL; - - g_hash_table_foreach (tracks, - (GHFunc) gst_cmml_track_list_merge_track, &list); - return list; -} - -GstCmmlTagClip * -gst_cmml_track_list_get_track_last_clip (GHashTable * tracks, - const gchar * track_name) -{ - GstCmmlTrack *track; - GList *res = NULL; - - g_return_val_if_fail (track_name != NULL, NULL); - - track = g_hash_table_lookup (tracks, track_name); - if (track && track->clips) - res = g_list_last (track->clips); - - return res ? GST_CMML_TAG_CLIP (res->data) : NULL; -} diff --git a/ext/annodex/gstcmmlutils.h b/ext/annodex/gstcmmlutils.h deleted file mode 100644 index 5aa2416348..0000000000 --- a/ext/annodex/gstcmmlutils.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * gstcmmlutils.h - GStreamer CMML utility functions - * Copyright (C) 2005 Alessandro Decina - * - * Authors: - * Alessandro Decina - * - * 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_CMML_CLOCK_TIME_H__ -#define __GST_CMML_CLOCK_TIME_H__ - -#include -#include "gstcmmltag.h" - -/* time utils */ -GstClockTime gst_cmml_clock_time_from_npt (const gchar * time); -GstClockTime gst_cmml_clock_time_from_smpte (const gchar * time); -gchar * gst_cmml_clock_time_to_npt (const GstClockTime time); -gint64 gst_cmml_clock_time_to_granule (GstClockTime prev_time, - GstClockTime current_time, gint64 granulerate_n, gint64 granulerate_d, - guint8 granuleshift); - -/* tracklist */ -GHashTable * gst_cmml_track_list_new (void); -void gst_cmml_track_list_destroy (GHashTable * tracks); -void gst_cmml_track_list_add_clip (GHashTable * tracks, GstCmmlTagClip * clip); -gboolean gst_cmml_track_list_del_clip (GHashTable * tracks, - GstCmmlTagClip * clip); -gboolean gst_cmml_track_list_has_clip (GHashTable * tracks, - GstCmmlTagClip * clip); -GstCmmlTagClip * gst_cmml_track_list_get_track_last_clip (GHashTable * tracks, - const gchar * track_name); -GList * gst_cmml_track_list_get_track_clips (GHashTable * tracks, - const gchar * track_name); -GList * gst_cmml_track_list_get_clips (GHashTable * tracks); -void gst_cmml_track_list_set_track_data (GHashTable * tracks, gpointer data); -gpointer gst_cmml_track_list_get_track_data (GHashTable * tracks); -#endif /* __GST_CMML_CLOCK_TIME_H__ */ diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index 7773f1a1b0..c6866d38ee 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -35,14 +35,6 @@ CLEANFILES = core.* test-registry.* clean-local: clean-local-check clean-local-orc -if USE_ANNODEX -check_annodex = \ - elements/cmmldec \ - elements/cmmlenc -else -check_annodex = -endif - if USE_FLAC check_flac = pipelines/flacdec else @@ -102,7 +94,6 @@ check_PROGRAMS = \ elements/aacparse \ elements/ac3parse \ elements/amrparse \ - $(check_annodex) \ elements/alphacolor \ elements/aspectratiocrop \ elements/audioamplify \ @@ -247,9 +238,6 @@ elements_rgvolume_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_API_VERSION) elements_spectrum_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS) elements_spectrum_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_API_VERSION) $(LDADD) -elements_cmmldec_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS) -elements_cmmlenc_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS) - elements_alphacolor_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS) elements_deinterlace_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS) diff --git a/tests/check/elements/.gitignore b/tests/check/elements/.gitignore index 1e2c8b2e4a..4d5da2f27c 100644 --- a/tests/check/elements/.gitignore +++ b/tests/check/elements/.gitignore @@ -20,8 +20,6 @@ autodetect avimux avisubtitle capssetter -cmmldec -cmmlenc deinterlace deinterleave equalizer diff --git a/tests/check/elements/cmmldec.c b/tests/check/elements/cmmldec.c deleted file mode 100644 index 5705ad01cb..0000000000 --- a/tests/check/elements/cmmldec.c +++ /dev/null @@ -1,653 +0,0 @@ -/* - * cmmldec.c - GStreamer CMML decoder test suite - * Copyright (C) 2005 Alessandro Decina - * - * Authors: - * Alessandro Decina - * - * 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. - */ - -/* FIXME 0.11: suppress warnings for deprecated API such as GValueArray - * with newer GLib versions (>= 2.31.0) */ -#define GLIB_DISABLE_DEPRECATION_WARNINGS - -#include -#include - -#define SINK_CAPS "text/x-cmml" -#define SRC_CAPS "text/x-cmml, encoded=(boolean)TRUE" - -#define IDENT_HEADER \ - "CMML\x00\x00\x00\x00"\ - "\x03\x00\x00\x00"\ - "\xe8\x03\x00\x00\x00\x00\x00\x00"\ - "\x01\x00\x00\x00\x00\x00\x00\x00"\ - "\x20" -#define IDENT_HEADER_SIZE 29 - -#define PREAMBLE_NO_PI \ - "\n"\ - "\n" -#define PREAMBLE PREAMBLE_NO_PI "" -#define PREAMBLE_DECODED PREAMBLE_NO_PI "" - -#define HEAD_TAG \ - ""\ - "The Research Hunter"\ - ""\ - ""\ - ""\ - ""\ - ""\ - "" - -#define HEAD_TAG_DECODED HEAD_TAG - -#define CLIP_TEMPLATE \ - ""\ - "http://www.csiro.au"\ - ""\ - "Welcome to CSIRO"\ - ""\ - "" - -#define CLIP_TEMPLATE_DECODED \ - ""\ - "http://www.csiro.au"\ - ""\ - "Welcome to CSIRO"\ - ""\ - "" - -#define EMPTY_CLIP_TEMPLATE \ - "" - -#define END_TAG \ - "" - -#define fail_unless_equals_flow_return(a, b) \ -G_STMT_START { \ - gchar *a_up = g_ascii_strup (gst_flow_get_name (a), -1); \ - gchar *b_up = g_ascii_strup (gst_flow_get_name (b), -1); \ - fail_unless (a == b, \ - "'" #a "' (GST_FLOW_%s) is not equal to '" #b "' (GST_FLOW_%s)", \ - a_up, b_up); \ - g_free (a_up); \ - g_free (b_up); \ -} G_STMT_END; - -static GstElement *cmmldec; - -static GstBus *bus; - -static GstFlowReturn flow; - -static GList *current_buf; - -static gint64 granulerate; - -static guint8 granuleshift; - -static GstPad *srcpad, *sinkpad; - -static GList *events; - -static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (SINK_CAPS) - ); - -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (SRC_CAPS) - ); - -static GstBuffer * -buffer_new (const gchar * buffer_data, guint size) -{ - GstBuffer *buffer; - guint8 *data; - - data = g_malloc (size); - memcpy (data, buffer_data, size); - - if (data) - buffer = gst_buffer_new_wrapped (data, size); - else - buffer = gst_buffer_new (); - - return buffer; -} - -static void -buffer_unref (void *buffer, void *user_data) -{ - ASSERT_OBJECT_REFCOUNT (buffer, "buf", 1); - gst_buffer_unref (GST_BUFFER (buffer)); -} - -static void -event_unref (void *event, void *user_data) -{ - ASSERT_OBJECT_REFCOUNT (event, "event", 1); - gst_event_unref (GST_EVENT (event)); -} - -static gboolean -cmmldec_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) -{ - GST_LOG ("received event %" GST_PTR_FORMAT, event); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_TAG: - events = g_list_append (events, event); - break; - default: - gst_event_unref (event); - break; - } - - return TRUE; -} - -static void -setup_cmmldec (void) -{ - GST_DEBUG ("setup_cmmldec"); - cmmldec = gst_check_setup_element ("cmmldec"); - srcpad = gst_check_setup_src_pad (cmmldec, &srctemplate); - sinkpad = gst_check_setup_sink_pad (cmmldec, &sinktemplate); - gst_pad_set_event_function (sinkpad, cmmldec_sink_event); - gst_pad_set_active (srcpad, TRUE); - gst_pad_set_active (sinkpad, TRUE); - - bus = gst_bus_new (); - gst_element_set_bus (cmmldec, bus); - - fail_unless (gst_element_set_state (cmmldec, - GST_STATE_PLAYING) != GST_STATE_CHANGE_FAILURE, - "could not set to playing"); - - granulerate = GST_SECOND / 1000; - granuleshift = 32; - buffers = NULL; -} - -static void -teardown_cmmldec (void) -{ - g_list_foreach (buffers, buffer_unref, NULL); - g_list_free (buffers); - buffers = NULL; - current_buf = NULL; - - gst_bus_set_flushing (bus, TRUE); - gst_object_unref (bus); - - GST_DEBUG ("teardown_cmmldec"); - gst_pad_set_active (srcpad, FALSE); - gst_pad_set_active (sinkpad, FALSE); - gst_check_teardown_src_pad (cmmldec); - gst_check_teardown_sink_pad (cmmldec); - gst_check_teardown_element (cmmldec); - - /* sticky stuff cleared above first */ - g_list_foreach (events, event_unref, NULL); - g_list_free (events); - events = NULL; -} - -static void -check_output_buffer_is_equal (const gchar * name, - const gchar * data, gint refcount) -{ - GstBuffer *buffer; - GstMapInfo map; - - if (current_buf == NULL) - current_buf = buffers; - else - current_buf = g_list_next (current_buf); - - fail_unless (current_buf != NULL); - - buffer = GST_BUFFER (current_buf->data); - gst_buffer_map (buffer, &map, GST_MAP_READ); - - ASSERT_OBJECT_REFCOUNT (buffer, name, refcount); - fail_unless (memcmp (map.data, data, map.size) == 0, - "'%s' (%s) is not equal to (%s)", name, map.data, data); - - gst_buffer_unmap (buffer, &map); -} - -static GstFlowReturn -push_data (const gchar * name, const gchar * data, gint size, gint64 granulepos) -{ - GstBuffer *buffer; - - buffer = buffer_new (data, size); - GST_BUFFER_OFFSET_END (buffer) = granulepos; - return gst_pad_push (srcpad, buffer); -} - -static void -push_caps (void) -{ - GstCaps *caps; - - caps = gst_caps_from_string (SRC_CAPS); - fail_unless (gst_pad_set_caps (srcpad, caps)); - gst_caps_unref (caps); -} - -static GObject * -cmml_tag_message_pop (GstBus * bus, const gchar * tag) -{ - GstTagList *taglist; - const GValue *value; - GObject *obj = NULL; - GstEvent *event; - - if (!events) - return NULL; - - event = (GstEvent *) events->data; - events = g_list_delete_link (events, events); - gst_event_parse_tag (event, &taglist); - - value = gst_tag_list_get_value_index (taglist, tag, 0); - if (value == NULL) - goto exit; - - obj = g_value_dup_object (value); - -exit: - gst_event_unref (event); - - return obj; -} - -static void -check_headers (void) -{ - GObject *head_tag; - - gchar *title, *base; - - GValueArray *meta; - - push_caps (); - - /* push the ident header */ - flow = push_data ("ident-header", IDENT_HEADER, IDENT_HEADER_SIZE, 0); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - - /* push the cmml preamble */ - flow = push_data ("preamble", PREAMBLE, strlen (PREAMBLE), 0); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - - /* push the head tag */ - flow = push_data ("head", HEAD_TAG, strlen (HEAD_TAG), 0); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - - fail_unless_equals_int (g_list_length (buffers), 2); - - /* check the decoded preamble */ - check_output_buffer_is_equal ("cmml-preamble-buffer", PREAMBLE_DECODED, 1); - - /* check the decoded head tag */ - check_output_buffer_is_equal ("head-tag-buffer", HEAD_TAG_DECODED, 1); - - /* check the GstCmmlTagHead tag object */ - head_tag = cmml_tag_message_pop (bus, GST_TAG_CMML_HEAD); - fail_unless (head_tag != NULL); - g_object_get (head_tag, - "title", &title, "base-uri", &base, "meta", &meta, NULL); - fail_unless_equals_string ("The Research Hunter", title); - fail_unless (base == NULL); - fail_unless (meta != NULL); - fail_unless_equals_int (meta->n_values, 10); - - g_free (title); - g_free (base); - g_value_array_free (meta); - g_object_unref (head_tag); -} - -static GstFlowReturn -push_clip_full (const gchar * name, const gchar * track, const gchar * template, - GstClockTime prev, GstClockTime start) -{ - gchar *clip; - - gint64 keyindex, keyoffset, granulepos; - - GstFlowReturn res; - - if (track == NULL) - track = "default"; - - if (prev == GST_CLOCK_TIME_NONE) - prev = 0; - - keyindex = prev / granulerate << granuleshift; - keyoffset = (start - prev) / granulerate; - granulepos = keyindex + keyoffset; - - clip = g_strdup_printf (template, name, track); - res = push_data (name, clip, strlen (clip), granulepos); - g_free (clip); - - return res; -} - -static GstFlowReturn -push_clip (const gchar * name, const gchar * track, - GstClockTime prev, GstClockTime start) -{ - return push_clip_full (name, track, CLIP_TEMPLATE, prev, start); -} - -static GstFlowReturn -push_empty_clip (const gchar * name, const gchar * track, GstClockTime start) -{ - return push_clip_full (name, track, - EMPTY_CLIP_TEMPLATE, GST_CLOCK_TIME_NONE, start); -} - - -static void -check_output_clip (const gchar * name, const gchar * track, - const gchar * start, const gchar * end) -{ - gchar *decoded_clip; - - if (track == NULL) - track = "default"; - - decoded_clip = g_strdup_printf (CLIP_TEMPLATE_DECODED, name, track, start); - check_output_buffer_is_equal (name, decoded_clip, 1); - g_free (decoded_clip); -} - -GST_START_TEST (test_dec) -{ - GstClockTime clip1_start = 1 * GST_SECOND + 234 * GST_MSECOND; - - GstClockTime clip2_start = clip1_start; - - GstClockTime clip3_start = - ((100 * 3600) + (59 * 60) + 59) * GST_SECOND + 678 * GST_MSECOND; - - check_headers (); - - flow = push_clip ("clip-1", "default", GST_CLOCK_TIME_NONE, clip1_start); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - - flow = push_clip ("clip-2", "othertrack", GST_CLOCK_TIME_NONE, clip2_start); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - - flow = push_clip ("clip-3", "default", clip1_start, clip3_start); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - - /* send EOS to flush clip-2 and clip-3 */ - gst_pad_send_event (GST_PAD_PEER (srcpad), gst_event_new_eos ()); - - check_output_clip ("clip-1", "default", "0:00:01.234", NULL); - check_output_clip ("clip-2", "othertrack", "0:00:01.234", NULL); - check_output_clip ("clip-3", "default", "100:59:59.678", NULL); - check_output_buffer_is_equal ("cmml-end-tag", END_TAG, 1); -} - -GST_END_TEST; - -GST_START_TEST (test_preamble_no_pi) -{ - push_caps (); - - flow = push_data ("ident-header", IDENT_HEADER, IDENT_HEADER_SIZE, 0); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - fail_unless_equals_int (g_list_length (buffers), 0); - - flow = push_data ("preamble-no-pi", - PREAMBLE_NO_PI, strlen (PREAMBLE_NO_PI), 0); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - fail_unless_equals_int (g_list_length (buffers), 1); - - check_output_buffer_is_equal ("cmml-preamble-buffer", - PREAMBLE_NO_PI "", 1); -} - -GST_END_TEST; - -GST_START_TEST (test_tags) -{ - GObject *tag; - - gboolean empty; - - gchar *id, *track; - - gint64 start_time, end_time; - - gchar *anchor_href, *anchor_text; - - gchar *img_src, *img_alt; - - gchar *desc; - - GValueArray *meta; - - GstClockTime clip1_start; - - check_headers (); - - clip1_start = 1 * GST_SECOND + 234 * GST_MSECOND; - flow = push_clip ("clip-1", "default", 0, clip1_start); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - - tag = cmml_tag_message_pop (bus, GST_TAG_CMML_CLIP); - fail_unless (tag != NULL); - - g_object_get (tag, "id", &id, "empty", &empty, "track", &track, - "start-time", &start_time, "end-time", &end_time, - "anchor-uri", &anchor_href, "anchor-text", &anchor_text, - "img-uri", &img_src, "img-alt", &img_alt, - "description", &desc, "meta", &meta, NULL); - - fail_unless (empty == FALSE); - fail_unless_equals_string (id, "clip-1"); - fail_unless_equals_string (track, "default"); - fail_unless_equals_int (start_time, 1 * GST_SECOND + 234 * GST_MSECOND); - fail_unless_equals_uint64 (end_time, GST_CLOCK_TIME_NONE); - fail_unless_equals_string (anchor_href, "http://www.csiro.au/"); - fail_unless_equals_string (anchor_text, "http://www.csiro.au"); - fail_unless_equals_string (img_src, "images/index1.jpg"); - fail_unless (img_alt == NULL); - fail_unless_equals_string (desc, "Welcome to CSIRO"); - fail_unless (meta != NULL); - fail_unless_equals_int (meta->n_values, 2); - - g_free (id); - g_free (track); - g_free (anchor_href); - g_free (anchor_text); - g_free (img_src); - g_free (img_alt); - g_free (desc); - g_value_array_free (meta); - g_object_unref (tag); -} - -GST_END_TEST; - -GST_START_TEST (test_wait_clip_end) -{ - GObject *tag; - - gchar *id; - - GstClockTime end_time = 0; - - GstClockTime clip1_start = 1 * GST_SECOND + 234 * GST_MSECOND; - - GstClockTime clip2_start = 2 * GST_SECOND + 234 * GST_MSECOND; - - GstClockTime clip3_start = 3 * GST_SECOND + 234 * GST_MSECOND; - - GstClockTime clip3_end = 4 * GST_SECOND + 234 * GST_MSECOND; - - GstClockTime clip4_start = 5 * GST_SECOND + 234 * GST_MSECOND; - - g_object_set (cmmldec, "wait-clip-end-time", TRUE, NULL); - - check_headers (); - - flow = push_clip ("clip-1", "default", 0, clip1_start); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - /* no tag has been posted yet */ - fail_unless (cmml_tag_message_pop (bus, GST_TAG_CMML_CLIP) == NULL); - - flow = push_clip ("clip-2", "default", clip1_start, clip2_start); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - - tag = cmml_tag_message_pop (bus, GST_TAG_CMML_CLIP); - fail_unless (tag != NULL); - g_object_get (tag, "id", &id, "end-time", &end_time, NULL); - /* clip-1 is posted when clip-2 is decoded. clip-1 ends when clip-2 starts */ - fail_unless_equals_string (id, "clip-1"); - fail_unless_equals_int (end_time, clip2_start); - g_free (id); - g_object_unref (tag); - - flow = push_clip ("clip-3", "default", clip2_start, clip3_start); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - - tag = cmml_tag_message_pop (bus, GST_TAG_CMML_CLIP); - fail_unless (tag != NULL); - g_object_get (tag, "id", &id, "end-time", &end_time, NULL); - /* clip-2 is posted when clip-3 is decoded. It ends when clip-3 starts */ - fail_unless_equals_string (id, "clip-2"); - fail_unless_equals_int (end_time, clip3_start); - g_free (id); - g_object_unref (tag); - - flow = push_empty_clip ("empty-clip", "default", clip3_end); - tag = cmml_tag_message_pop (bus, GST_TAG_CMML_CLIP); - fail_unless (tag != NULL); - g_object_get (tag, "id", &id, "end-time", &end_time, NULL); - /* clip-3 ends when empty-clip is decoded */ - fail_unless_equals_string (id, "clip-3"); - fail_unless_equals_int (end_time, clip3_end); - g_free (id); - g_object_unref (tag); - - flow = push_clip ("clip-4", "default", clip3_start, clip4_start); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - - /* an empty clip just marks the end of the previous one, so no tag is posted - * for empty-clip */ - fail_unless (cmml_tag_message_pop (bus, GST_TAG_CMML_CLIP) == NULL); - /* send EOS to flush clip-4 */ - gst_pad_send_event (GST_PAD_PEER (srcpad), gst_event_new_eos ()); - - tag = cmml_tag_message_pop (bus, GST_TAG_CMML_CLIP); - fail_unless (tag != NULL); - g_object_get (tag, "id", &id, NULL); - fail_unless_equals_string (id, "clip-4"); - g_free (id); - g_object_unref (tag); -} - -GST_END_TEST; - -GST_START_TEST (test_weird_input) -{ - const gchar *bad_xml = ""; - - push_caps (); - - /* malformed ident header */ - flow = push_data ("bad-ident-header", "CMML\0\0\0\0garbage", 15, 0); - fail_unless_equals_flow_return (flow, GST_FLOW_ERROR); - - /* push invalid xml */ - flow = push_data ("bad-xml", bad_xml, strlen (bad_xml), 0); - fail_unless_equals_flow_return (flow, GST_FLOW_ERROR); - - /* and now for something completely different: an empty buffer. This is valid - * as 'NIL' EOS pages are allowed */ - flow = push_data ("empty-eos", NULL, 0, 0); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); -} - -GST_END_TEST; - -GST_START_TEST (test_sink_query_convert) -{ - guint64 keyindex, keyoffset, granulepos; - - GstClockTime index_time, offset_time; - - GstFormat dstfmt = GST_FORMAT_TIME; - - gint64 dstval; - - /* send headers to set the granulerate */ - check_headers (); - - /* create a 1|1 granulepos */ - index_time = 1 * GST_SECOND; - offset_time = 1 * GST_SECOND; - - keyindex = (index_time / granulerate) << granuleshift; - keyoffset = offset_time / granulerate; - granulepos = keyindex + keyoffset; - - fail_unless (gst_pad_query_convert (GST_PAD_PEER (srcpad), - GST_FORMAT_DEFAULT, granulepos, dstfmt, &dstval)); - - fail_unless (dstfmt == GST_FORMAT_TIME); - /* fail unless dstval == index + offset */ - fail_unless_equals_int (2 * GST_SECOND, dstval); -} - -GST_END_TEST; - -static Suite * -cmmldec_suite (void) -{ - Suite *s = suite_create ("cmmldec"); - - TCase *tc_general = tcase_create ("general"); - - suite_add_tcase (s, tc_general); - tcase_add_checked_fixture (tc_general, setup_cmmldec, teardown_cmmldec); - tcase_add_test (tc_general, test_dec); - tcase_add_test (tc_general, test_tags); - tcase_add_test (tc_general, test_preamble_no_pi); - tcase_add_test (tc_general, test_wait_clip_end); - tcase_add_test (tc_general, test_sink_query_convert); - tcase_add_test (tc_general, test_weird_input); - - return s; -} - -GST_CHECK_MAIN (cmmldec); diff --git a/tests/check/elements/cmmlenc.c b/tests/check/elements/cmmlenc.c deleted file mode 100644 index a546202d51..0000000000 --- a/tests/check/elements/cmmlenc.c +++ /dev/null @@ -1,505 +0,0 @@ -/* - * cmmlenc.c - GStreamer CMML decoder test suite - * Copyright (C) 2005 Alessandro Decina - * - * Authors: - * Alessandro Decina - * - * 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 - -#include - -#define SINK_CAPS "text/x-cmml" -#define SRC_CAPS "text/x-cmml,encoded=(boolean)FALSE" - -#define IDENT_HEADER \ - "CMML\x00\x00\x00\x00"\ - "\x03\x00\x00\x00"\ - "\xe8\x03\x00\x00\x00\x00\x00\x00"\ - "\x01\x00\x00\x00\x00\x00\x00\x00"\ - "\x20" - -#define XML_PREAMBLE \ - "\n"\ - "\n" - -#define START_TAG \ - "" - -#define PROCESSING_INSTRUCTION \ - "" - -#define PREAMBLE \ - XML_PREAMBLE START_TAG - -#define PREAMBLE_ENCODED \ - XML_PREAMBLE PROCESSING_INSTRUCTION - -#define STREAM_TAG \ - ""\ - ""\ - ""\ - "" - -#define STREAM_TAG_ENCODED STREAM_TAG - -#define HEAD_TAG \ - ""\ - "The Research Hunter"\ - ""\ - ""\ - ""\ - ""\ - ""\ - "" - -#define HEAD_TAG_ENCODED HEAD_TAG - -#define CLIP_TEMPLATE \ - ""\ - "http://www.annodex.org"\ - ""\ - "Annodex Foundation"\ - ""\ - "" - -#define ENDED_CLIP_TEMPLATE \ - ""\ - "http://www.annodex.org"\ - ""\ - "Annodex Foundation"\ - ""\ - "" - -#define CLIP_TEMPLATE_ENCODED \ - ""\ - "http://www.annodex.org"\ - ""\ - "Annodex Foundation"\ - ""\ - "" - -#define EMPTY_CLIP_TEMPLATE_ENCODED \ - "" - -#define fail_unless_equals_flow_return(a, b) \ -G_STMT_START { \ - gchar *a_up = g_ascii_strup (gst_flow_get_name (a), -1); \ - gchar *b_up = g_ascii_strup (gst_flow_get_name (b), -1); \ - fail_unless (a == b, \ - "'" #a "' (GST_FLOW_%s) is not equal to '" #b "' (GST_FLOW_%s)", \ - a_up, b_up); \ - g_free (a_up); \ - g_free (b_up); \ -} G_STMT_END; - -static GList *current_buf; -static guint64 granulerate; -static guint8 granuleshift; -static GstElement *cmmlenc; -static GstBus *bus; -static GstFlowReturn flow; -static GstPad *srcpad, *sinkpad; - -static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (SINK_CAPS) - ); - -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (SRC_CAPS) - ); - -static GstBuffer * -buffer_new (const gchar * buffer_data, guint size) -{ - GstBuffer *buffer; - guint8 *data; - - data = g_malloc (size); - memcpy (data, buffer_data, size); - - buffer = gst_buffer_new_wrapped (data, size); - - return buffer; -} - -static void -buffer_unref (void *buffer, void *user_data) -{ - gst_buffer_unref (GST_BUFFER (buffer)); -} - -static void -setup_cmmlenc (void) -{ - guint64 granulerate_n, granulerate_d; - - GST_DEBUG ("setup_cmmlenc"); - - cmmlenc = gst_check_setup_element ("cmmlenc"); - srcpad = gst_check_setup_src_pad (cmmlenc, &srctemplate); - sinkpad = gst_check_setup_sink_pad (cmmlenc, &sinktemplate); - gst_pad_set_active (srcpad, TRUE); - gst_pad_set_active (sinkpad, TRUE); - - bus = gst_bus_new (); - gst_element_set_bus (cmmlenc, bus); - - fail_unless (gst_element_set_state (cmmlenc, - GST_STATE_PLAYING) != GST_STATE_CHANGE_FAILURE, - "could not set to playing"); - - g_object_get (cmmlenc, "granule-rate-numerator", &granulerate_n, - "granule-rate-denominator", &granulerate_d, - "granule-shift", &granuleshift, NULL); - - granulerate = GST_SECOND * granulerate_d / granulerate_n; -} - -static void -teardown_cmmlenc (void) -{ - /* free encoded buffers */ - g_list_foreach (buffers, buffer_unref, NULL); - g_list_free (buffers); - buffers = NULL; - current_buf = NULL; - - gst_bus_set_flushing (bus, TRUE); - gst_object_unref (bus); - - GST_DEBUG ("teardown_cmmlenc"); - gst_pad_set_active (srcpad, FALSE); - gst_pad_set_active (sinkpad, FALSE); - gst_check_teardown_src_pad (cmmlenc); - gst_check_teardown_sink_pad (cmmlenc); - gst_check_teardown_element (cmmlenc); -} - -static void -check_output_buffer_is_equal (const gchar * name, - const gchar * data, gint refcount) -{ - GstBuffer *buffer; - GstMapInfo map; - - if (current_buf == NULL) - current_buf = buffers; - else - current_buf = g_list_next (current_buf); - - fail_unless (current_buf != NULL); - buffer = GST_BUFFER (current_buf->data); - gst_buffer_map (buffer, &map, GST_MAP_READ); - - ASSERT_OBJECT_REFCOUNT (buffer, name, refcount); - fail_unless (memcmp (map.data, data, map.size) == 0, - "'%s' (%s) is not equal to (%s)", name, map.data, data); - - gst_buffer_unmap (buffer, &map); -} - -static GstFlowReturn -push_data (const gchar * name, const gchar * data, gint size) -{ - GstBuffer *buffer; - GstFlowReturn res; - - buffer = buffer_new (data, size); - res = gst_pad_push (srcpad, buffer); - - return res; -} - -static void -push_caps (void) -{ - GstCaps *caps; - - caps = gst_caps_from_string (SRC_CAPS); - fail_unless (gst_pad_set_caps (srcpad, caps)); - gst_caps_unref (caps); -} - -static void -check_headers (void) -{ - push_caps (); - - /* push the cmml start tag */ - flow = push_data ("preamble", PREAMBLE, strlen (PREAMBLE)); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - - /* push the stream tag */ - flow = push_data ("stream", STREAM_TAG, strlen (STREAM_TAG)); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - /* push the head tag */ - flow = push_data ("head", HEAD_TAG, strlen (HEAD_TAG)); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - - /* should output 3 buffers: the ident, preamble and head headers */ - fail_unless_equals_int (g_list_length (buffers), 3); - - /* check the ident header */ - check_output_buffer_is_equal ("cmml-ident-buffer", IDENT_HEADER, 1); - - /* check the cmml processing instruction */ - check_output_buffer_is_equal ("cmml-preamble-buffer", PREAMBLE_ENCODED, 1); - - /* check the encoded head tag */ - check_output_buffer_is_equal ("head-tag-buffer", HEAD_TAG_ENCODED, 1); -} - -static GstFlowReturn -push_clip (const gchar * name, const gchar * track, - const gchar * start, const gchar * end) -{ - gchar *clip; - GstFlowReturn res; - - if (end != NULL) - clip = g_strdup_printf (ENDED_CLIP_TEMPLATE, name, track, start, end); - else - clip = g_strdup_printf (CLIP_TEMPLATE, name, track, start); - res = push_data (name, clip, strlen (clip)); - g_free (clip); - - return res; -} - -static void -check_clip_times (GstBuffer * buffer, GstClockTime start, GstClockTime prev) -{ - guint64 keyindex, keyoffset, granulepos; - - granulepos = GST_BUFFER_OFFSET_END (buffer); - if (granuleshift == 0 || granuleshift == 64) - keyindex = 0; - else - keyindex = granulepos >> granuleshift; - keyoffset = granulepos - (keyindex << granuleshift); - fail_unless_equals_uint64 (keyindex * granulerate, prev); - fail_unless_equals_uint64 ((keyindex + keyoffset) * granulerate, start); -} - -static void -check_clip (const gchar * name, const gchar * track, - GstClockTime start, GstClockTime prev) -{ - gchar *encoded_clip; - GstBuffer *buffer; - - encoded_clip = g_strdup_printf (CLIP_TEMPLATE_ENCODED, name, track); - check_output_buffer_is_equal (name, encoded_clip, 1); - g_free (encoded_clip); - buffer = GST_BUFFER (current_buf->data); - check_clip_times (buffer, start, prev); -} - -static void -check_empty_clip (const gchar * name, const gchar * track, - GstClockTime start, GstClockTime prev) -{ - gchar *encoded_clip; - GstBuffer *buffer; - - encoded_clip = g_strdup_printf (EMPTY_CLIP_TEMPLATE_ENCODED, track); - check_output_buffer_is_equal (name, encoded_clip, 1); - g_free (encoded_clip); - buffer = GST_BUFFER (current_buf->data); - check_clip_times (buffer, start, prev); -} - -GST_START_TEST (test_enc) -{ - check_headers (); - - flow = push_clip ("clip-1", "default", "1.234", NULL); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - check_clip ("clip-1", "default", 1 * GST_SECOND + 234 * GST_MSECOND, 0); - - flow = push_clip ("clip-2", "default", "5.678", NULL); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - check_clip ("clip-2", "default", - 5 * GST_SECOND + 678 * GST_MSECOND, 1 * GST_SECOND + 234 * GST_MSECOND); - - flow = push_clip ("clip-3", "othertrack", "9.123", NULL); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - check_clip ("clip-3", "othertrack", 9 * GST_SECOND + 123 * GST_MSECOND, 0); - - flow = push_data ("end-tag", "", strlen ("")); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - check_output_buffer_is_equal ("cmml-eos", NULL, 1); -} - -GST_END_TEST; - -GST_START_TEST (test_clip_end_time) -{ - check_headers (); - - /* push a clip that starts at 1.234 an ends at 2.234 */ - flow = push_clip ("clip-1", "default", "1.234", "2.234"); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - check_clip ("clip-1", "default", 1 * GST_SECOND + 234 * GST_MSECOND, 0); - - /* now check that the encoder created an empty clip starting at 2.234 to mark - * the end of clip-1 */ - check_empty_clip ("clip-1-end", "default", - 2 * GST_SECOND + 234 * GST_MSECOND, 1 * GST_SECOND + 234 * GST_MSECOND); - - /* now push another clip on the same track and check that the keyindex part of - * the granulepos points to clip-1 and not to the empty clip */ - flow = push_clip ("clip-2", "default", "5", NULL); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - check_clip ("clip-2", "default", - 5 * GST_SECOND, 1 * GST_SECOND + 234 * GST_MSECOND); -} - -GST_END_TEST; - -GST_START_TEST (test_time_order) -{ - check_headers (); - - /* clips belonging to the same track must have start times in non decreasing - * order */ - flow = push_clip ("clip-1", "default", "1000:00:00.000", NULL); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - check_clip ("clip-1", "default", 3600 * 1000 * GST_SECOND, 0); - - /* this will make the encoder throw an error message */ - flow = push_clip ("clip-2", "default", "5.678", NULL); - fail_unless_equals_flow_return (flow, GST_FLOW_ERROR); - - flow = push_clip ("clip-3", "default", "1000:00:00.001", NULL); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - check_clip ("clip-3", "default", - 3600 * 1000 * GST_SECOND + 1 * GST_MSECOND, 3600 * 1000 * GST_SECOND); - - /* tracks don't interfere with each other */ - flow = push_clip ("clip-4", "othertrack", "9.123", NULL); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - check_clip ("clip-4", "othertrack", 9 * GST_SECOND + 123 * GST_MSECOND, 0); -} - -GST_END_TEST; - -GST_START_TEST (test_time_parsing) -{ - check_headers (); - - flow = push_clip ("bad-msecs", "default", "0.1000", NULL); - fail_unless_equals_flow_return (flow, GST_FLOW_ERROR); - - flow = push_clip ("bad-secs", "default", "00:00:60.123", NULL); - fail_unless_equals_flow_return (flow, GST_FLOW_ERROR); - - flow = push_clip ("bad-minutes", "default", "00:60:12.345", NULL); - fail_unless_equals_flow_return (flow, GST_FLOW_ERROR); - - /* this fails since we can't store 5124096 * 3600 * GST_SECOND in a - * GstClockTime */ - flow = push_clip ("bad-hours", "default", "5124096:00:00.000", NULL); - fail_unless_equals_flow_return (flow, GST_FLOW_ERROR); -} - -GST_END_TEST; - -GST_START_TEST (test_time_limits) -{ - check_headers (); - - /* ugly hack to make sure that the following checks actually overflow parsing - * the times in gst_cmml_clock_time_from_npt rather than converting them to - * granulepos in gst_cmml_clock_time_to_granule */ - granuleshift = 64; - g_object_set (cmmlenc, "granule-shift", granuleshift, NULL); - - /* 5124095:34:33.709 is the max npt-hhmmss time representable with - * GstClockTime */ - flow = push_clip ("max-npt-hhmmss", "foo", "5124095:34:33.709", NULL); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - check_clip ("max-npt-hhmmss", "foo", - (GstClockTime) 5124095 * 3600 * GST_SECOND + 34 * 60 * GST_SECOND + - 33 * GST_SECOND + 709 * GST_MSECOND, 0); - - flow = push_clip ("overflow-max-npt-hhmmss", "overflows", - "5124095:34:33.710", NULL); - fail_unless_equals_flow_return (flow, GST_FLOW_ERROR); - - /* 18446744073.709 is the max ntp-sec time */ - flow = push_clip ("max-npt-secs", "bar", "18446744073.709", NULL); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - check_clip ("max-npt-secs", "bar", - (GstClockTime) 5124095 * 3600 * GST_SECOND + 34 * 60 * GST_SECOND + - 33 * GST_SECOND + 709 * GST_MSECOND, 0); - - /* overflow doing 18446744074 * GST_SECOND */ - flow = push_clip ("overflow-max-npt-secs", "overflows", - "18446744074.000", NULL); - fail_unless_equals_flow_return (flow, GST_FLOW_ERROR); - - /* overflow doing seconds + milliseconds */ - flow = push_clip ("overflow-max-npt-secs-msecs", "overflows", - "18446744073.710", NULL); - fail_unless_equals_flow_return (flow, GST_FLOW_ERROR); - - /* reset granuleshift to 32 to check keyoffset overflows in - * gst_cmml_clock_time_to_granule */ - granuleshift = 32; - g_object_set (cmmlenc, "granule-shift", granuleshift, NULL); - - /* 1193:02:47.295 is the max time we can encode in the keyoffset part of a - * granulepos given a granuleshift of 32 */ - flow = push_clip ("max-granule-keyoffset", "baz", "1193:02:47.295", NULL); - fail_unless_equals_flow_return (flow, GST_FLOW_OK); - check_clip ("max-granule-keyoffset", "baz", - 1193 * 3600 * GST_SECOND + 2 * 60 * GST_SECOND + - 47 * GST_SECOND + 295 * GST_MSECOND, 0); - - flow = push_clip ("overflow-max-granule-keyoffset", "overflows", - "1193:02:47.296", NULL); - fail_unless_equals_flow_return (flow, GST_FLOW_ERROR); -} - -GST_END_TEST; - -static Suite * -cmmlenc_suite (void) -{ - Suite *s = suite_create ("cmmlenc"); - TCase *tc_general = tcase_create ("general"); - - suite_add_tcase (s, tc_general); - tcase_add_checked_fixture (tc_general, setup_cmmlenc, teardown_cmmlenc); - tcase_add_test (tc_general, test_enc); - tcase_add_test (tc_general, test_clip_end_time); - tcase_add_test (tc_general, test_time_order); - tcase_add_test (tc_general, test_time_parsing); - tcase_add_test (tc_general, test_time_limits); - - return s; -} - -GST_CHECK_MAIN (cmmlenc);