ext/mad/gstid3tag.c: deprecate id3tag element and replace with id3demux/id3mux.

Original commit message from CVS:
* ext/mad/gstid3tag.c: (gst_id3_tag_get_type),
(gst_id3_tag_class_init), (gst_id3_tag_get_caps),
(gst_id3_tag_add_src_pad), (gst_id3_tag_init),
(gst_id3_tag_set_property), (gst_id3_tag_do_caps_nego),
(gst_id3_tag_src_link), (gst_id3_tag_chain),
(gst_id3_tag_change_state), (plugin_init):
deprecate id3tag element and replace with id3demux/id3mux.
great side effect: this ugly file is now even uglier, yay!
* ext/mad/gstmad.h:
remove non-available function
update for new get_type
This commit is contained in:
Benjamin Otte 2004-04-17 17:52:35 +00:00
parent b9bea37e2b
commit d539f7b4c1
3 changed files with 192 additions and 106 deletions

View file

@ -1,3 +1,17 @@
2004-04-17 Benjamin Otte <in7y118@public.uni-hamburg.de>
* ext/mad/gstid3tag.c: (gst_id3_tag_get_type),
(gst_id3_tag_class_init), (gst_id3_tag_get_caps),
(gst_id3_tag_add_src_pad), (gst_id3_tag_init),
(gst_id3_tag_set_property), (gst_id3_tag_do_caps_nego),
(gst_id3_tag_src_link), (gst_id3_tag_chain),
(gst_id3_tag_change_state), (plugin_init):
deprecate id3tag element and replace with id3demux/id3mux.
great side effect: this ugly file is now even uglier, yay!
* ext/mad/gstmad.h:
remove non-available function
update for new get_type
2004-04-17 Benjamin Otte <in7y118@public.uni-hamburg.de> 2004-04-17 Benjamin Otte <in7y118@public.uni-hamburg.de>
* configure.ac: * configure.ac:

View file

@ -1,7 +1,7 @@
/* GStreamer /* GStreamer
* Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de> * Copyright (C) 2003-2004 Benjamin Otte <otte@gnome.org>
* *
* gstid3tagsetter.c: plugin for reading / modifying id3 tags * gstid3tag.c: plugin for reading / modifying id3 tags
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public * modify it under the terms of the GNU Library General Public
@ -30,11 +30,12 @@
GST_DEBUG_CATEGORY_STATIC (gst_id3_tag_debug); GST_DEBUG_CATEGORY_STATIC (gst_id3_tag_debug);
#define GST_CAT_DEFAULT gst_id3_tag_debug #define GST_CAT_DEFAULT gst_id3_tag_debug
#define GST_TYPE_ID3_TAG (gst_id3_tag_get_type()) #define GST_TYPE_ID3_TAG (gst_id3_tag_get_type(GST_ID3_TAG_PARSE_BASE ))
#define GST_ID3_TAG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ID3_TAG, GstID3Tag)) #define GST_ID3_TAG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ID3_TAG, GstID3Tag))
#define GST_ID3_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ID3_TAG, GstID3Tag)) #define GST_ID3_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ID3_TAG, GstID3TagClass))
#define GST_IS_ID3_TAG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ID3_TAG)) #define GST_IS_ID3_TAG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ID3_TAG))
#define GST_IS_ID3_TAG_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ID3_TAG)) #define GST_IS_ID3_TAG_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ID3_TAG))
#define GST_ID3_TAG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_ID3_TAG, GstID3TagClass))
typedef struct _GstID3Tag GstID3Tag; typedef struct _GstID3Tag GstID3Tag;
typedef struct _GstID3TagClass GstID3TagClass; typedef struct _GstID3TagClass GstID3TagClass;
@ -52,13 +53,18 @@ GstID3TagState;
typedef enum typedef enum
{ {
GST_ID3_TAG_PARSE_UNKNOWN, GST_ID3_TAG_PARSE_BASE = 0,
GST_ID3_TAG_PARSE_TAG, GST_ID3_TAG_PARSE_DEMUX = 1,
GST_ID3_TAG_PARSE_WRITE, GST_ID3_TAG_PARSE_MUX = 2,
GST_ID3_TAG_PARSE_PARSE GST_ID3_TAG_PARSE_ANY = 3
} }
GstID3ParseMode; GstID3ParseMode;
#define IS_DEMUXER(tag) ((tag)->parse_mode & GST_ID3_TAG_PARSE_DEMUX)
#define IS_MUXER(tag) ((tag)->parse_mode & GST_ID3_TAG_PARSE_MUX)
#define CAN_BE_DEMUXER(tag) (GST_ID3_TAG_GET_CLASS(tag)->type & GST_ID3_TAG_PARSE_DEMUX)
#define CAN_BE_MUXER(tag) (GST_ID3_TAG_GET_CLASS(tag)->type & GST_ID3_TAG_PARSE_MUX)
struct _GstID3Tag struct _GstID3Tag
{ {
GstElement element; GstElement element;
@ -92,16 +98,10 @@ struct _GstID3Tag
struct _GstID3TagClass struct _GstID3TagClass
{ {
GstElementClass parent_class; GstElementClass parent_class;
GstID3ParseMode type;
}; };
/* elementfactory information */
static GstElementDetails gst_id3_tag_details =
GST_ELEMENT_DETAILS ("id3 tag extractor",
"Tag",
"Extract tagging information from mp3s",
"Benjamin Otte <in7y118@public.uni-hamburg.de>");
/* signals and args */ /* signals and args */
enum enum
{ {
@ -120,15 +120,31 @@ enum
GST_DEBUG_CATEGORY_EXTERN (mad_debug); GST_DEBUG_CATEGORY_EXTERN (mad_debug);
static GstStaticPadTemplate id3_tag_src_template_factory = static GstStaticPadTemplate id3_tag_src_any_template_factory =
GST_STATIC_PAD_TEMPLATE ("src", GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC, GST_PAD_SRC,
/* FIXME: for spider - GST_PAD_ALWAYS, */ /* FIXME: for spider - should be GST_PAD_ALWAYS, */
GST_PAD_SOMETIMES, GST_PAD_SOMETIMES,
GST_STATIC_CAPS ("ANY") GST_STATIC_CAPS ("ANY")
); );
static GstStaticPadTemplate id3_tag_sink_template_factory = static GstStaticPadTemplate id3_tag_src_id3_template_factory =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
/* FIXME: for spider - should be GST_PAD_ALWAYS, */
GST_PAD_SOMETIMES,
GST_STATIC_CAPS ("application/x-id3")
);
static GstStaticPadTemplate id3_tag_sink_any_template_factory =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
/* FIXME: find a way to extend this generically */
GST_STATIC_CAPS ("audio/mpeg; audio/x-flac")
);
static GstStaticPadTemplate id3_tag_sink_id3_template_factory =
GST_STATIC_PAD_TEMPLATE ("sink", GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
@ -136,9 +152,8 @@ GST_STATIC_PAD_TEMPLATE ("sink",
); );
static void gst_id3_tag_base_init (gpointer g_class); static void gst_id3_tag_class_init (gpointer g_class, gpointer class_data);
static void gst_id3_tag_class_init (GstID3TagClass * klass); static void gst_id3_tag_init (GTypeInstance * instance, gpointer g_class);
static void gst_id3_tag_init (GstID3Tag * tag);
static void gst_id3_tag_set_property (GObject * object, static void gst_id3_tag_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec); guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_id3_tag_get_property (GObject * object, static void gst_id3_tag_get_property (GObject * object,
@ -162,21 +177,26 @@ static GstElementClass *parent_class = NULL;
/* static guint gst_id3_tag_signals[LAST_SIGNAL] = { 0 }; */ /* static guint gst_id3_tag_signals[LAST_SIGNAL] = { 0 }; */
GType GType
gst_id3_tag_get_type (void) gst_id3_tag_get_type (guint type)
{ {
static GType id3_tag_type = 0; static GType id3_tag_type[4] = { 0, 0, 0, 0 };
static gchar *name[4] = { "GstID3TagBase", "GstID3Demux", "GstID3Mux",
"GstID3Tag"
};
if (!id3_tag_type) { g_assert (type < 4);
static const GTypeInfo id3_tag_info = {
if (!id3_tag_type[type]) {
GTypeInfo id3_tag_info = {
sizeof (GstID3TagClass), sizeof (GstID3TagClass),
gst_id3_tag_base_init,
NULL,
(GClassInitFunc) gst_id3_tag_class_init,
NULL, NULL,
NULL, NULL,
gst_id3_tag_class_init,
NULL,
GUINT_TO_POINTER (type),
sizeof (GstID3Tag), sizeof (GstID3Tag),
0, 0,
(GInstanceInitFunc) gst_id3_tag_init, gst_id3_tag_init,
}; };
static const GInterfaceInfo tag_setter_info = { static const GInterfaceInfo tag_setter_info = {
NULL, NULL,
@ -184,55 +204,80 @@ gst_id3_tag_get_type (void)
NULL NULL
}; };
id3_tag_type = id3_tag_type[type] = g_type_register_static (
g_type_register_static (GST_TYPE_ELEMENT, "GstID3Tag", &id3_tag_info, (type == GST_ID3_TAG_PARSE_BASE) ? GST_TYPE_ELEMENT :
0); GST_TYPE_ID3_TAG, name[type], &id3_tag_info, 0);
g_type_add_interface_static (id3_tag_type, GST_TYPE_TAG_SETTER, if (type & GST_ID3_TAG_PARSE_DEMUX) {
&tag_setter_info); g_type_add_interface_static (id3_tag_type[type], GST_TYPE_TAG_SETTER,
&tag_setter_info);
GST_DEBUG_CATEGORY_INIT (gst_id3_tag_debug, "id3tag", 0, }
"id3 tag reader / setter");
} }
return id3_tag_type; return id3_tag_type[type];
} }
/* elementfactory information */
GstElementDetails gst_id3_tag_details[3] = {
GST_ELEMENT_DETAILS ("id3 tag extractor",
"Codec/Demuxer",
"Extract ID3 tagging information",
"Benjamin Otte <otte@gnome.org>"),
GST_ELEMENT_DETAILS ("id3 muxer",
"Codec/Muxer",
"Add ID3 tagging information",
"Benjamin Otte <otte@gnome.org>"),
GST_ELEMENT_DETAILS ("id3 tag extractor",
"Tag",
"Extract tagging information from mp3s",
"Benjamin Otte <otte@gnome.org>")
};
static void static void
gst_id3_tag_base_init (gpointer g_class) gst_id3_tag_class_init (gpointer g_class, gpointer class_data)
{ {
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
GstID3TagClass *tag_class = GST_ID3_TAG_CLASS (g_class);
gst_element_class_set_details (element_class, &gst_id3_tag_details); tag_class->type = GPOINTER_TO_UINT (class_data);
gst_element_class_add_pad_template (element_class, if (tag_class->type == GST_ID3_TAG_PARSE_BASE) {
gst_static_pad_template_get (&id3_tag_sink_template_factory)); parent_class = g_type_class_peek_parent (g_class);
gst_element_class_add_pad_template (element_class, gstelement_class->change_state = gst_id3_tag_change_state;
gst_static_pad_template_get (&id3_tag_src_template_factory)); } else {
} gst_element_class_set_details (gstelement_class,
static void &gst_id3_tag_details[tag_class->type - 1]);
gst_id3_tag_class_init (GstID3TagClass * klass) }
{
GstElementClass *gstelement_class;
GObjectClass *gobject_class;
gstelement_class = (GstElementClass *) klass; if (tag_class->type & GST_ID3_TAG_PARSE_DEMUX) {
gobject_class = (GObjectClass *) klass; g_object_class_install_property (gobject_class, ARG_V2_TAG,
g_param_spec_boolean ("v2-tag", "add version 2 tag",
"Add version 2 tag at start of file", TRUE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
g_object_class_install_property (gobject_class, ARG_V1_TAG,
g_param_spec_boolean ("v1-tag", "add version 1 tag",
"Add version 1 tag at end of file", FALSE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&id3_tag_src_any_template_factory));
} else {
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&id3_tag_src_id3_template_factory));
}
parent_class = g_type_class_ref (GST_TYPE_ELEMENT); if (tag_class->type & GST_ID3_TAG_PARSE_MUX) {
g_object_class_install_property (gobject_class, ARG_PREFER_V1,
gstelement_class->change_state = gst_id3_tag_change_state; g_param_spec_boolean ("prefer-v1", "prefer version 1 tag",
"Prefer tags from tag at end of file", FALSE,
g_object_class_install_property (gobject_class, ARG_V1_TAG, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
g_param_spec_boolean ("v1-tag", "add version 1 tag", }
"Add version 1 tag at end of file", FALSE, if (tag_class->type == GST_ID3_TAG_PARSE_MUX) {
G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); gst_element_class_add_pad_template (gstelement_class,
g_object_class_install_property (gobject_class, ARG_V2_TAG, gst_static_pad_template_get (&id3_tag_sink_any_template_factory));
g_param_spec_boolean ("v2-tag", "add version 2 tag", } else {
"Add version 2 tag at start of file", TRUE, gst_element_class_add_pad_template (gstelement_class,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); gst_static_pad_template_get (&id3_tag_sink_id3_template_factory));
g_object_class_install_property (gobject_class, ARG_PREFER_V1, }
g_param_spec_boolean ("prefer-v1", "prefer version 1 tag",
"Prefer tags from tag at end of file", FALSE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_id3_tag_set_property); gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_id3_tag_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_id3_tag_get_property); gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_id3_tag_get_property);
@ -244,13 +289,15 @@ gst_id3_tag_get_caps (GstPad * pad)
GstID3Tag *tag = GST_ID3_TAG (gst_pad_get_parent (pad)); GstID3Tag *tag = GST_ID3_TAG (gst_pad_get_parent (pad));
if (tag->found_caps) { if (tag->found_caps) {
GstCaps *caps; GstCaps *caps = gst_caps_copy (tag->found_caps);
caps = gst_caps_from_string ("application/x-gst-tags; application/x-id3"); if (CAN_BE_MUXER (tag)) {
gst_caps_append (caps, gst_caps_copy (tag->found_caps)); gst_caps_append (caps,
gst_caps_from_string ("application/x-gst-tags; application/x-id3"));
}
return caps; return caps;
} else { } else {
return gst_caps_new_any (); return gst_caps_copy (gst_pad_get_pad_template_caps (pad));
} }
} }
@ -259,8 +306,8 @@ gst_id3_tag_add_src_pad (GstID3Tag * tag)
{ {
g_assert (tag->srcpad == NULL); g_assert (tag->srcpad == NULL);
tag->srcpad = tag->srcpad =
gst_pad_new_from_template (gst_static_pad_template_get gst_pad_new_from_template (gst_element_class_get_pad_template
(&id3_tag_src_template_factory), "src"); (GST_ELEMENT_GET_CLASS (tag), "src"), "src");
gst_pad_set_event_function (tag->srcpad, gst_pad_set_event_function (tag->srcpad,
GST_DEBUG_FUNCPTR (gst_id3_tag_src_event)); GST_DEBUG_FUNCPTR (gst_id3_tag_src_event));
gst_pad_set_event_mask_function (tag->srcpad, gst_pad_set_event_mask_function (tag->srcpad,
@ -275,21 +322,25 @@ gst_id3_tag_add_src_pad (GstID3Tag * tag)
GST_DEBUG_FUNCPTR (gst_id3_tag_src_link)); GST_DEBUG_FUNCPTR (gst_id3_tag_src_link));
gst_element_add_pad (GST_ELEMENT (tag), tag->srcpad); gst_element_add_pad (GST_ELEMENT (tag), tag->srcpad);
} }
static void static void
gst_id3_tag_init (GstID3Tag * tag) gst_id3_tag_init (GTypeInstance * instance, gpointer g_class)
{ {
/* create the sink and src pads */ GstID3Tag *tag = GST_ID3_TAG (instance);
tag->sinkpad =
gst_pad_new_from_template (gst_static_pad_template_get if (GST_ID3_TAG_GET_CLASS (tag)->type != GST_ID3_TAG_PARSE_BASE) {
(&id3_tag_sink_template_factory), "sink"); /* create the sink and src pads */
gst_element_add_pad (GST_ELEMENT (tag), tag->sinkpad); g_print ("creating sinkpad\n");
gst_pad_set_chain_function (tag->sinkpad, tag->sinkpad =
GST_DEBUG_FUNCPTR (gst_id3_tag_chain)); gst_pad_new_from_template (gst_element_class_get_pad_template
(GST_ELEMENT_CLASS (g_class), "sink"), "sink");
gst_element_add_pad (GST_ELEMENT (tag), tag->sinkpad);
gst_pad_set_chain_function (tag->sinkpad,
GST_DEBUG_FUNCPTR (gst_id3_tag_chain));
}
/* FIXME: for the alli^H^H^H^Hspider - gst_id3_tag_add_src_pad (tag); */ /* FIXME: for the alli^H^H^H^Hspider - gst_id3_tag_add_src_pad (tag); */
tag->parse_mode = GST_ID3_TAG_PARSE_BASE;
tag->state = GST_ID3_TAG_STATE_READING_V2_TAG;
tag->parse_mode = GST_ID3_TAG_PARSE_UNKNOWN;
tag->buffer = NULL; tag->buffer = NULL;
GST_FLAG_SET (tag, GST_ELEMENT_EVENT_AWARE); GST_FLAG_SET (tag, GST_ELEMENT_EVENT_AWARE);
@ -319,6 +370,13 @@ gst_id3_tag_set_property (GObject * object, guint prop_id, const GValue * value,
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
} }
/* make sure we render at least one tag */
if (GST_ID3_TAG_GET_CLASS (tag)->type == GST_ID3_TAG_PARSE_MUX &&
!tag->v1tag_render && !tag->v2tag_render) {
g_object_set (object, prop_id == ARG_V1_TAG ? "v2-tag" : "v1-tag", TRUE,
NULL);
}
} }
static void static void
gst_id3_tag_get_property (GObject * object, guint prop_id, GValue * value, gst_id3_tag_get_property (GObject * object, guint prop_id, GValue * value,
@ -850,7 +908,7 @@ gst_id3_tag_do_typefind (GstID3Tag * tag, GstBuffer * buffer)
static gboolean static gboolean
gst_id3_tag_do_caps_nego (GstID3Tag * tag, GstBuffer * buffer) gst_id3_tag_do_caps_nego (GstID3Tag * tag, GstBuffer * buffer)
{ {
if (buffer != NULL) { if (buffer != NULL && CAN_BE_DEMUXER (tag)) {
tag->found_caps = gst_id3_tag_do_typefind (tag, buffer); tag->found_caps = gst_id3_tag_do_typefind (tag, buffer);
if (!tag->found_caps) { if (!tag->found_caps) {
return FALSE; return FALSE;
@ -859,7 +917,7 @@ gst_id3_tag_do_caps_nego (GstID3Tag * tag, GstBuffer * buffer)
if (!tag->srcpad) if (!tag->srcpad)
gst_id3_tag_add_src_pad (tag); gst_id3_tag_add_src_pad (tag);
if (!gst_pad_is_linked (tag->srcpad)) { if (!gst_pad_is_linked (tag->srcpad)) {
tag->parse_mode = GST_ID3_TAG_PARSE_TAG; tag->parse_mode = GST_ID3_TAG_GET_CLASS (tag)->type;
return TRUE; return TRUE;
} else { } else {
return gst_pad_renegotiate (tag->srcpad) != GST_PAD_LINK_REFUSED; return gst_pad_renegotiate (tag->srcpad) != GST_PAD_LINK_REFUSED;
@ -874,19 +932,23 @@ gst_id3_tag_src_link (GstPad * pad, const GstCaps * caps)
tag = GST_ID3_TAG (gst_pad_get_parent (pad)); tag = GST_ID3_TAG (gst_pad_get_parent (pad));
if (!tag->found_caps) if (!tag->found_caps && CAN_BE_DEMUXER (tag))
return GST_PAD_LINK_DELAYED; return GST_PAD_LINK_DELAYED;
if (!CAN_BE_MUXER (tag) || !CAN_BE_DEMUXER (tag)) {
tag->parse_mode = GST_ID3_TAG_GET_CLASS (tag)->type;
return GST_PAD_LINK_OK;
}
mimetype = gst_structure_get_name (gst_caps_get_structure (caps, 0)); mimetype = gst_structure_get_name (gst_caps_get_structure (caps, 0));
if (strcmp (mimetype, "application/x-id3") == 0) { if (strcmp (mimetype, "application/x-id3") == 0) {
tag->parse_mode = GST_ID3_TAG_PARSE_WRITE; tag->parse_mode = GST_ID3_TAG_PARSE_MUX;
GST_LOG_OBJECT (tag, "normal operation, using application/x-id3 output"); GST_LOG_OBJECT (tag, "normal operation, using application/x-id3 output");
} else if (strcmp (mimetype, "application/x-gst-tags") == 0) { } else if (strcmp (mimetype, "application/x-gst-tags") == 0) {
tag->parse_mode = GST_ID3_TAG_PARSE_TAG; tag->parse_mode = GST_ID3_TAG_PARSE_ANY;
GST_LOG_OBJECT (tag, "fast operation, just outputting tags"); GST_LOG_OBJECT (tag, "fast operation, just outputting tags");
} else { } else {
tag->parse_mode = GST_ID3_TAG_PARSE_PARSE; tag->parse_mode = GST_ID3_TAG_PARSE_DEMUX;
GST_LOG_OBJECT (tag, "parsing operation, extracting tags"); GST_LOG_OBJECT (tag, "parsing operation, extracting tags");
} }
@ -966,7 +1028,7 @@ gst_id3_tag_chain (GstPad * pad, GstData * data)
} }
gst_data_unref (GST_DATA (tag->buffer)); gst_data_unref (GST_DATA (tag->buffer));
tag->buffer = NULL; tag->buffer = NULL;
if (tag->parse_mode != GST_ID3_TAG_PARSE_TAG) { if (tag->parse_mode != GST_ID3_TAG_PARSE_ANY) {
/* seek to beginning */ /* seek to beginning */
GST_LOG_OBJECT (tag, "seeking back to beginning"); GST_LOG_OBJECT (tag, "seeking back to beginning");
if (gst_pad_send_event (GST_PAD_PEER (tag->sinkpad), if (gst_pad_send_event (GST_PAD_PEER (tag->sinkpad),
@ -1052,7 +1114,7 @@ gst_id3_tag_chain (GstPad * pad, GstData * data)
g_assert (tag->buffer == NULL); g_assert (tag->buffer == NULL);
gst_id3_tag_send_tag_event (tag); gst_id3_tag_send_tag_event (tag);
if (tag->parse_mode == GST_ID3_TAG_PARSE_WRITE && tag->v2tag_render) { if (IS_MUXER (tag) && tag->v2tag_render) {
struct id3_tag *id3; struct id3_tag *id3;
GstTagList *merged; GstTagList *merged;
GstBuffer *tag_buffer; GstBuffer *tag_buffer;
@ -1079,13 +1141,14 @@ gst_id3_tag_chain (GstPad * pad, GstData * data)
} }
gst_id3_tag_set_state (tag, GST_ID3_TAG_STATE_NORMAL); gst_id3_tag_set_state (tag, GST_ID3_TAG_STATE_NORMAL);
tag->v1tag_size_new = (tag->v1tag_render && tag->v1tag_size_new = (tag->v1tag_render &&
tag->parse_mode == GST_ID3_TAG_PARSE_WRITE && IS_MUXER (tag) &&
(tag->parsed_tags != NULL || (tag->parsed_tags != NULL ||
gst_tag_setter_get_list (GST_TAG_SETTER (tag)) != gst_tag_setter_get_list (GST_TAG_SETTER (tag)) !=
NULL)) ? 128 : 0; NULL)) ? 128 : 0;
/* fall through */ /* fall through */
case GST_ID3_TAG_STATE_NORMAL: case GST_ID3_TAG_STATE_NORMAL:
if (tag->parse_mode == GST_ID3_TAG_PARSE_TAG) { if (tag->parse_mode == GST_ID3_TAG_PARSE_ANY) {
gst_data_unref (GST_DATA (buffer));
gst_element_set_eos (GST_ELEMENT (tag)); gst_element_set_eos (GST_ELEMENT (tag));
gst_pad_push (tag->srcpad, GST_DATA (gst_event_new (GST_EVENT_EOS))); gst_pad_push (tag->srcpad, GST_DATA (gst_event_new (GST_EVENT_EOS)));
} else { } else {
@ -1122,9 +1185,13 @@ gst_id3_tag_change_state (GstElement * element)
tag->v1tag_size = 0; tag->v1tag_size = 0;
tag->v1tag_offset = G_MAXUINT64; tag->v1tag_offset = G_MAXUINT64;
tag->v2tag_size = 0; tag->v2tag_size = 0;
if (CAN_BE_DEMUXER (tag)) {
gst_id3_tag_set_state (tag, GST_ID3_TAG_STATE_READING_V2_TAG);
} else {
gst_id3_tag_set_state (tag, GST_ID3_TAG_STATE_NORMAL_START);
}
break; break;
case GST_STATE_PAUSED_TO_PLAYING: case GST_STATE_PAUSED_TO_PLAYING:
/* do something to get out of the chain function faster */
break; break;
case GST_STATE_PLAYING_TO_PAUSED: case GST_STATE_PLAYING_TO_PAUSED:
break; break;
@ -1145,7 +1212,7 @@ gst_id3_tag_change_state (GstElement * element)
gst_caps_free (tag->found_caps); gst_caps_free (tag->found_caps);
tag->found_caps = NULL; tag->found_caps = NULL;
} }
tag->parse_mode = GST_ID3_TAG_PARSE_UNKNOWN; tag->parse_mode = GST_ID3_TAG_PARSE_BASE;
break; break;
case GST_STATE_READY_TO_NULL: case GST_STATE_READY_TO_NULL:
break; break;
@ -1162,14 +1229,20 @@ plugin_init (GstPlugin * plugin)
if (!gst_library_load ("gsttags")) if (!gst_library_load ("gsttags"))
return FALSE; return FALSE;
/* We register id3tag with a rank one less than mad so that mad always
gets picked before id3tag if possible. This avoids multiple plugging
of id3tag in the autoplugger for now. */
if (!gst_element_register (plugin, "mad", GST_RANK_PRIMARY, if (!gst_element_register (plugin, "mad", GST_RANK_PRIMARY,
gst_mad_get_type ()) gst_mad_get_type ())
|| !gst_element_register (plugin, "id3tag", GST_RANK_PRIMARY - 1, || !gst_element_register (plugin, "id3demux", GST_RANK_PRIMARY,
gst_id3_tag_get_type ())) gst_id3_tag_get_type (GST_ID3_TAG_PARSE_DEMUX))
|| !gst_element_register (plugin, "id3mux", GST_RANK_PRIMARY,
gst_id3_tag_get_type (GST_ID3_TAG_PARSE_MUX))
/* FIXME 0.9: remove this element */
|| !gst_element_register (plugin, "id3tag", GST_RANK_NONE,
gst_id3_tag_get_type (GST_ID3_TAG_PARSE_ANY))) {
return FALSE; return FALSE;
}
GST_DEBUG_CATEGORY_INIT (gst_id3_tag_debug, "id3tag", 0,
"id3 tag reader / setter");
return TRUE; return TRUE;
} }

View file

@ -30,8 +30,7 @@ G_BEGIN_DECLS
GType gst_mad_get_type (void); GType gst_mad_get_type (void);
GType gst_id3_parse_get_type (void); GType gst_id3_tag_get_type (guint type);
GType gst_id3_tag_get_type (void);
GstTagList* gst_mad_id3_to_tag_list (const struct id3_tag * tag); GstTagList* gst_mad_id3_to_tag_list (const struct id3_tag * tag);
struct id3_tag * gst_mad_tag_list_to_id3_tag (GstTagList * list); struct id3_tag * gst_mad_tag_list_to_id3_tag (GstTagList * list);