diff --git a/ChangeLog b/ChangeLog index eb5a674b72..f8455c0c70 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2004-05-02 Ronald Bultje + + * gst/asfdemux/Makefile.am: + * gst/asfdemux/asfheaders.c: + * gst/asfdemux/asfheaders.h: + * gst/asfdemux/gstasf.c: (plugin_init): + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_get_type), + (gst_asf_demux_base_init), (gst_asf_demux_process_comment), + (gst_asf_demux_setup_pad): + * gst/asfdemux/gstasfdemux.h: + * gst/asfdemux/gstasfmux.c: + * gst/asfdemux/gstasfmux.h: + Add tagging support to demuxer, split out registration in its own + file instead of in demux (hacky), and prevent having some tables + in our memory multiple times (in asfheaders.h). + 2004-05-01 Ronald Bultje * gst/matroska/matroska-demux.c: diff --git a/gst/asfdemux/Makefile.am b/gst/asfdemux/Makefile.am index 5b0b29aa8a..8c0335752a 100644 --- a/gst/asfdemux/Makefile.am +++ b/gst/asfdemux/Makefile.am @@ -1,7 +1,6 @@ - plugin_LTLIBRARIES = libgstasf.la -libgstasf_la_SOURCES = gstasfmux.c gstasfdemux.c +libgstasf_la_SOURCES = gstasfmux.c gstasfdemux.c gstasf.c asfheaders.c libgstasf_la_CFLAGS = $(GST_CFLAGS) libgstasf_la_LIBADD = libgstasf_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) diff --git a/gst/asfdemux/asfheaders.c b/gst/asfdemux/asfheaders.c new file mode 100644 index 0000000000..aa383b01b7 --- /dev/null +++ b/gst/asfdemux/asfheaders.c @@ -0,0 +1,98 @@ +/* GStreamer + * Copyright (C) <1999> Erik Walthinsen + * + * 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 "asfheaders.h" + +ASFGuidHash asf_correction_guids[] = { + {ASF_CORRECTION_ON, {0xBFC3CD50, 0x11CF618F, 0xAA00B28B, 0x20E2B400} + } + , +/* { ASF_CORRECTION_OFF, { 0x20FB5700, 0x11CF5B55, 0x8000FDA8, 0x2B445C5F }},*/ + {ASF_CORRECTION_OFF, {0x49F1A440, 0x11D04ECE, 0xA000ACA3, 0xF64803C9} + } + , + {ASF_CORRECTION_UNDEFINED, {0, 0, 0, 0} + } + , +}; + +ASFGuidHash asf_stream_guids[] = { + {ASF_STREAM_VIDEO, {0xBC19EFC0, 0x11CF5B4D, 0x8000FDA8, 0x2B445C5F} + } + , + {ASF_STREAM_AUDIO, {0xF8699E40, 0x11CF5B4D, 0x8000FDA8, 0x2B445C5F} + } + , + {ASF_STREAM_UNDEFINED, {0, 0, 0, 0} + } + , +}; + +ASFGuidHash asf_object_guids[] = { + {ASF_OBJ_STREAM, {0xB7DC0791, 0x11CFA9B7, 0xC000E68E, 0x6553200C} + } + , + {ASF_OBJ_DATA, {0x75b22636, 0x11cf668e, 0xAA00D9a6, 0x6Cce6200} + } + , + {ASF_OBJ_FILE, {0x8CABDCA1, 0x11CFA947, 0xC000E48E, 0x6553200C} + } + , + {ASF_OBJ_HEADER, {0x75B22630, 0x11CF668E, 0xAA00D9A6, 0x6CCE6200} + } + , + {ASF_OBJ_CONCEAL_NONE, {0x20fb5700, 0x11cf5b55, 0x8000FDa8, 0x2B445C5f} + } + , + {ASF_OBJ_COMMENT, {0x75b22633, 0x11cf668e, 0xAA00D9a6, 0x6Cce6200} + } + , + {ASF_OBJ_CODEC_COMMENT, {0x86D15240, 0x11D0311D, 0xA000A4A3, 0xF64803C9} + } + , + {ASF_OBJ_CODEC_COMMENT1, {0x86d15241, 0x11d0311d, 0xA000A4a3, 0xF64803c9} + } + , + {ASF_OBJ_INDEX, {0x33000890, 0x11cfe5b1, 0xA000F489, 0xCB4903c9} + } + , + {ASF_OBJ_HEAD1, {0x5fbf03b5, 0x11cfa92e, 0xC000E38e, 0x6553200c} + } + , + {ASF_OBJ_HEAD2, {0xabd3d211, 0x11cfa9ba, 0xC000E68e, 0x6553200c} + } + , + {ASF_OBJ_PADDING, {0x1806D474, 0x4509CADF, 0xAB9ABAA4, 0xE8AA96CD} + } + , + {ASF_OBJ_BITRATE_PROPS, {0x7bf875ce, 0x11d1468d, 0x6000828d, 0xb2a2c997} + } + , + {ASF_OBJ_EXT_CONTENT_DESC, {0xd2d0a440, 0x11d2e307, 0xa000f097, 0x50a85ec9} + } + , + {ASF_OBJ_BITRATE_MUTEX, {0xd6e229dc, 0x11d135da, 0xa0003490, 0xbe4903c9} + } + , + {ASF_OBJ_UNDEFINED, {0, 0, 0, 0} + } + , +}; diff --git a/gst/asfdemux/asfheaders.h b/gst/asfdemux/asfheaders.h index 0f8106ccb7..2e12bca0d5 100644 --- a/gst/asfdemux/asfheaders.h +++ b/gst/asfdemux/asfheaders.h @@ -17,8 +17,8 @@ * Boston, MA 02111-1307, USA. */ -#ifndef ASFHEADERS_H -#define ASFHEADERS_H +#ifndef __ASFHEADERS_H__ +#define __ASFHEADERS_H__ typedef struct { guint32 v1; @@ -65,18 +65,9 @@ enum { ASF_CORRECTION_OFF, }; -static ASFGuidHash asf_correction_guids[] = { - { ASF_CORRECTION_ON, { 0xBFC3CD50, 0x11CF618F, 0xAA00B28B, 0x20E2B400 }}, -/* { ASF_CORRECTION_OFF, { 0x20FB5700, 0x11CF5B55, 0x8000FDA8, 0x2B445C5F }},*/ - { ASF_CORRECTION_OFF, { 0x49F1A440, 0x11D04ECE, 0xA000ACA3, 0xF64803C9 }}, - { ASF_CORRECTION_UNDEFINED, { 0, 0, 0, 0 }}, -}; +extern ASFGuidHash asf_correction_guids[]; -static ASFGuidHash asf_stream_guids[] = { - { ASF_STREAM_VIDEO, { 0xBC19EFC0, 0x11CF5B4D, 0x8000FDA8, 0x2B445C5F }}, - { ASF_STREAM_AUDIO, { 0xF8699E40, 0x11CF5B4D, 0x8000FDA8, 0x2B445C5F }}, - { ASF_STREAM_UNDEFINED, { 0, 0, 0, 0 }}, -}; +extern ASFGuidHash asf_stream_guids[]; struct _asf_obj_header { guint32 num_objects; @@ -233,25 +224,6 @@ struct _asf_bitrate_record { typedef struct _asf_bitrate_record asf_bitrate_record; -static ASFGuidHash asf_object_guids[] = { - { ASF_OBJ_STREAM, { 0xB7DC0791, 0x11CFA9B7, 0xC000E68E, 0x6553200C }}, - { ASF_OBJ_DATA, { 0x75b22636, 0x11cf668e, 0xAA00D9a6, 0x6Cce6200 }}, - { ASF_OBJ_FILE, { 0x8CABDCA1, 0x11CFA947, 0xC000E48E, 0x6553200C }}, - { ASF_OBJ_HEADER, { 0x75B22630, 0x11CF668E, 0xAA00D9A6, 0x6CCE6200 }}, - { ASF_OBJ_CONCEAL_NONE, { 0x20fb5700, 0x11cf5b55, 0x8000FDa8, 0x2B445C5f }}, - { ASF_OBJ_COMMENT, { 0x75b22633, 0x11cf668e, 0xAA00D9a6, 0x6Cce6200 }}, - { ASF_OBJ_CODEC_COMMENT, { 0x86D15240, 0x11D0311D, 0xA000A4A3, 0xF64803C9 }}, - { ASF_OBJ_CODEC_COMMENT1, { 0x86d15241, 0x11d0311d, 0xA000A4a3, 0xF64803c9 }}, - { ASF_OBJ_INDEX, { 0x33000890, 0x11cfe5b1, 0xA000F489, 0xCB4903c9 }}, - { ASF_OBJ_HEAD1, { 0x5fbf03b5, 0x11cfa92e, 0xC000E38e, 0x6553200c }}, - { ASF_OBJ_HEAD2, { 0xabd3d211, 0x11cfa9ba, 0xC000E68e, 0x6553200c }}, - { ASF_OBJ_PADDING, { 0x1806D474, 0x4509CADF, 0xAB9ABAA4, 0xE8AA96CD }}, - { ASF_OBJ_BITRATE_PROPS, { 0x7bf875ce, 0x11d1468d, 0x6000828d, 0xb2a2c997 }}, - { ASF_OBJ_EXT_CONTENT_DESC, { 0xd2d0a440, 0x11d2e307, 0xa000f097, 0x50a85ec9 }}, - { ASF_OBJ_BITRATE_MUTEX, { 0xd6e229dc, 0x11d135da, 0xa0003490, 0xbe4903c9 }}, - { ASF_OBJ_UNDEFINED, { 0, 0, 0, 0 }}, -}; +extern ASFGuidHash asf_object_guids[]; - -/* ASFHEADERS_H */ -#endif +#endif /* __ASFHEADERS_H__ */ diff --git a/gst/asfdemux/gstasf.c b/gst/asfdemux/gstasf.c new file mode 100644 index 0000000000..12e614e469 --- /dev/null +++ b/gst/asfdemux/gstasf.c @@ -0,0 +1,48 @@ +/* GStreamer + * Copyright (C) <1999> Erik Walthinsen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "gstasfdemux.h" +#include "gstasfmux.h" + +static gboolean +plugin_init (GstPlugin * plugin) +{ + if (!gst_library_load ("gstbytestream")) + return FALSE; + + if (!gst_element_register (plugin, "asfdemux", GST_RANK_PRIMARY, + GST_TYPE_ASF_DEMUX) + || !gst_element_register (plugin, "asfmux", GST_RANK_NONE, + GST_TYPE_ASFMUX)) + return FALSE; + + return TRUE; +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "asf", + "Demuxes and muxes audio and video in Microsofts ASF format", + plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN) diff --git a/gst/asfdemux/gstasfdemux.c b/gst/asfdemux/gstasfdemux.c index 477c43381e..1292207d15 100644 --- a/gst/asfdemux/gstasfdemux.c +++ b/gst/asfdemux/gstasfdemux.c @@ -21,19 +21,12 @@ #ifdef HAVE_CONFIG_H #include "config.h" #endif + #include #include -#include "gstasfdemux.h" -#include "gstasfmux.h" /* for the type registering */ -#include "asfheaders.h" -/* elementfactory information */ -static GstElementDetails gst_asf_demux_details = { - "ASF Demuxer", - "Codec/Demuxer", - "Demultiplexes ASF Streams", - "Owen Fraser-Green ", -}; +#include "gstasfdemux.h" +#include "asfheaders.h" static GstStaticPadTemplate gst_asf_demux_sink_template = GST_STATIC_PAD_TEMPLATE ("sink", @@ -83,7 +76,7 @@ static GstPadTemplate *videosrctempl, *audiosrctempl; static GstElementClass *parent_class = NULL; GType -asf_demux_get_type (void) +gst_asf_demux_get_type (void) { static GType asf_demux_type = 0; @@ -103,6 +96,8 @@ asf_demux_get_type (void) asf_demux_type = g_type_register_static (GST_TYPE_ELEMENT, "GstASFDemux", &asf_demux_info, 0); + + GST_DEBUG_CATEGORY_INIT (asf_debug, "asfdemux", 0, "asf demuxer element"); } return asf_demux_type; } @@ -111,6 +106,12 @@ static void gst_asf_demux_base_init (gpointer g_class) { GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + static GstElementDetails gst_asf_demux_details = { + "ASF Demuxer", + "Codec/Demuxer", + "Demultiplexes ASF Streams", + "Owen Fraser-Green " + }; int i; GstCaps *audcaps, *vidcaps, *temp; guint32 vid_list[] = { @@ -518,6 +519,17 @@ gst_asf_demux_process_comment (GstASFDemux * asf_demux, guint64 * obj_size) { asf_obj_comment object; GstByteStream *bs = asf_demux->bs; + gchar *utf8_comments[5] = { NULL, NULL, NULL, NULL, NULL }; + guchar *data; + const gchar *tags[5] = { GST_TAG_TITLE, GST_TAG_ARTIST, GST_TAG_COPYRIGHT, + GST_TAG_COMMENT, NULL /* ? */ + }; + guint16 *lengths = (guint16 *) & object; + gint i; + gsize in, out; + GstTagList *taglist; + const GList *padlist; + GValue value = { 0 }; GST_INFO ("Object is a comment."); @@ -527,15 +539,52 @@ gst_asf_demux_process_comment (GstASFDemux * asf_demux, guint64 * obj_size) ("Comment lengths: title=%d author=%d copyright=%d description=%d rating=%d", object.title_length, object.author_length, object.copyright_length, object.description_length, object.rating_length); + g_print ("comment\n"); + for (i = 0; i < 5; i++) { + /* might be just '/0', '/0'... */ + if (lengths[i] > 2 && lengths[i] % 2 == 0) { + if (gst_bytestream_peek_bytes (bs, &data, lengths[i]) != lengths[i]) + goto fail; + gst_bytestream_flush_fast (bs, lengths[i]); - /* We don't do anything with them at the moment so just skip them */ - gst_bytestream_flush (bs, object.title_length); - gst_bytestream_flush (bs, object.author_length); - gst_bytestream_flush (bs, object.copyright_length); - gst_bytestream_flush (bs, object.description_length); - gst_bytestream_flush (bs, object.rating_length); + /* check null-termination (malicious input) */ + if (data[lengths[i] - 1] != '\0' || data[lengths[i] - 2] != '\0') + continue; + + /* convert to UTF-8 */ + utf8_comments[i] = g_convert (data, lengths[i], + "UTF-8", "Unicode", &in, &out, NULL); + } + } + + /* parse metadata into taglist */ + taglist = gst_tag_list_new (); + g_value_init (&value, G_TYPE_STRING); + for (i = 0; i < 5; i++) { + if (utf8_comments[i] && tags[i]) { + g_value_set_string (&value, utf8_comments[i]); + gst_tag_list_add_values (taglist, GST_TAG_MERGE_APPEND, + tags[i], &value, NULL); + g_free (utf8_comments[i]); + } + } + g_value_unset (&value); + + for (padlist = gst_element_get_pad_list (GST_ELEMENT (asf_demux)); + padlist != NULL; padlist = padlist->next) { + if (GST_PAD_IS_SRC (padlist->data) && GST_PAD_IS_USABLE (padlist->data)) { + gst_pad_push (GST_PAD (padlist->data), + GST_DATA (gst_event_new_tag (taglist))); + } + } + gst_element_found_tags (GST_ELEMENT (asf_demux), taglist); return TRUE; + +fail: + for (i = 0; i < 5; i++) + g_free (utf8_comments[i]); + return FALSE; } @@ -1730,27 +1779,3 @@ gst_asf_demux_setup_pad (GstASFDemux * asf_demux, return TRUE; } - -static gboolean -plugin_init (GstPlugin * plugin) -{ - if (!gst_library_load ("gstbytestream")) - return FALSE; - - /* create an elementfactory for the asf_demux element */ - if (!gst_element_register (plugin, "asfdemux", GST_RANK_PRIMARY, - GST_TYPE_ASF_DEMUX) - || !gst_element_register (plugin, "asfmux", GST_RANK_NONE, - GST_TYPE_ASFMUX)) - return FALSE; - - GST_DEBUG_CATEGORY_INIT (asf_debug, "asfdemux", 0, "asf demuxer element"); - - return TRUE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "asf", - "Demuxes and muxes audio and video in Microsofts ASF format", - plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN) diff --git a/gst/asfdemux/gstasfdemux.h b/gst/asfdemux/gstasfdemux.h index 3f11071f65..0a8c6905fe 100644 --- a/gst/asfdemux/gstasfdemux.h +++ b/gst/asfdemux/gstasfdemux.h @@ -23,12 +23,11 @@ #include #include -#include "asfheaders.h" G_BEGIN_DECLS #define GST_TYPE_ASF_DEMUX \ - (asf_demux_get_type()) + (gst_asf_demux_get_type()) #define GST_ASF_DEMUX(obj) \ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ASF_DEMUX,GstASFDemux)) #define GST_ASF_DEMUX_CLASS(klass) \ @@ -107,11 +106,7 @@ struct _GstASFDemuxClass { GstElementClass parent_class; }; -GType gst_asf_demux_get_type(void); - -gboolean gst_asf_demux_plugin_init (GModule *module, GstPlugin *plugin); - - +GType gst_asf_demux_get_type (void); G_END_DECLS diff --git a/gst/asfdemux/gstasfmux.c b/gst/asfdemux/gstasfmux.c index 6ada468575..8a3f9861df 100644 --- a/gst/asfdemux/gstasfmux.c +++ b/gst/asfdemux/gstasfmux.c @@ -46,6 +46,7 @@ /* for audio codec IDs */ #include +#include "asfheaders.h" #include "gstasfmux.h" /* elementfactory information */ diff --git a/gst/asfdemux/gstasfmux.h b/gst/asfdemux/gstasfmux.h index 115261abc1..9c1d8a7eca 100644 --- a/gst/asfdemux/gstasfmux.h +++ b/gst/asfdemux/gstasfmux.h @@ -21,6 +21,7 @@ #define __GST_ASFMUX_H__ #include + #include "asfheaders.h" #ifdef __cplusplus