ext/mad/gstid3tag.c: Fix typefinding in id3demux, and then remove it in favour of the new LGPL id3demux in gst-plugin...

Original commit message from CVS:
* ext/mad/gstid3tag.c: (gst_id3_tag_do_typefind),
(gst_id3_tag_do_caps_nego), (gst_id3_tag_chain), (plugin_init):
Fix typefinding in id3demux, and then remove it in favour
of the new LGPL id3demux in gst-plugins-good
* ext/mad/gstmad.c: (gst_mad_dispose):
dispose can run more than once.
This commit is contained in:
Jan Schmidt 2005-12-18 15:08:15 +00:00
parent 80d81b7e34
commit 16d1543b88
3 changed files with 93 additions and 63 deletions

View File

@ -1,3 +1,12 @@
2005-12-18 Jan Schmidt <thaytan@mad.scientist.com>
* ext/mad/gstid3tag.c: (gst_id3_tag_do_typefind),
(gst_id3_tag_do_caps_nego), (gst_id3_tag_chain), (plugin_init):
Fix typefinding in id3demux, and then remove it in favour
of the new LGPL id3demux in gst-plugins-good
* ext/mad/gstmad.c: (gst_mad_dispose):
dispose can run more than once.
2005-12-16 Stefan Kost <ensonic@users.sf.net> 2005-12-16 Stefan Kost <ensonic@users.sf.net>
* gst/asfdemux/gstasfmux.c: (gst_asfmux_file_start): * gst/asfdemux/gstasfmux.c: (gst_asfmux_file_start):

View File

@ -27,7 +27,9 @@
#include <string.h> #include <string.h>
#include <gst/gsttagsetter.h> #include <gst/gsttagsetter.h>
#define ID3_TYPE_FIND_SIZE 40960 #define ID3_TYPE_FIND_MIN_SIZE 3072
#define ID3_TYPE_FIND_MAX_SIZE 40960
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
@ -1039,11 +1041,11 @@ gst_id3_tag_do_typefind (GstID3Tag * tag, GstBuffer * buffer)
gst_plugin_feature_list_free (type_list); gst_plugin_feature_list_free (type_list);
if (find.best_probability > 0) { if (find.best_probability > 0) {
return find.caps; return find.caps;
} else { }
GST_ELEMENT_ERROR (tag, CORE, CAPS, (NULL), ("no caps found"));
return NULL; return NULL;
} }
}
static gboolean static gboolean
gst_id3_tag_do_caps_nego (GstID3Tag * tag, GstBuffer * buffer) gst_id3_tag_do_caps_nego (GstID3Tag * tag, GstBuffer * buffer)
{ {
@ -1052,6 +1054,8 @@ gst_id3_tag_do_caps_nego (GstID3Tag * tag, GstBuffer * buffer)
if (!tag->found_caps) { if (!tag->found_caps) {
return FALSE; return FALSE;
} }
GST_DEBUG_OBJECT (tag, "Found contained data caps %" GST_PTR_FORMAT,
tag->found_caps);
} }
if (tag->srcpad == NULL) { if (tag->srcpad == NULL) {
gst_id3_tag_add_src_pad (tag); gst_id3_tag_add_src_pad (tag);
@ -1126,9 +1130,15 @@ static GstFlowReturn
gst_id3_tag_chain (GstPad * pad, GstBuffer * buffer) gst_id3_tag_chain (GstPad * pad, GstBuffer * buffer)
{ {
GstID3Tag *tag; GstID3Tag *tag;
GstBuffer *temp;
tag = GST_ID3_TAG (gst_pad_get_parent (pad)); tag = GST_ID3_TAG (gst_pad_get_parent (pad));
GST_DEBUG_OBJECT (tag, "Chain, state = %d", tag->state); GST_LOG_OBJECT (tag, "Chain, state = %d", tag->state);
if (tag->buffer) {
buffer = gst_buffer_join (tag->buffer, buffer);
tag->buffer = NULL;
}
switch (tag->state) { switch (tag->state) {
case GST_ID3_TAG_STATE_SEEKING_TO_V1_TAG: case GST_ID3_TAG_STATE_SEEKING_TO_V1_TAG:
@ -1137,27 +1147,24 @@ gst_id3_tag_chain (GstPad * pad, GstBuffer * buffer)
gst_buffer_unref (buffer); gst_buffer_unref (buffer);
return GST_FLOW_OK; return GST_FLOW_OK;
case GST_ID3_TAG_STATE_READING_V1_TAG: case GST_ID3_TAG_STATE_READING_V1_TAG:
if (tag->buffer) { if (GST_BUFFER_SIZE (buffer) < 128) {
GstBuffer *temp;
temp = gst_buffer_merge (tag->buffer, buffer);
gst_buffer_unref (tag->buffer);
tag->buffer = temp;
gst_buffer_unref (buffer);
} else {
tag->buffer = buffer; tag->buffer = buffer;
tag->v1tag_offset = buffer->offset;
}
if (GST_BUFFER_SIZE (tag->buffer) < 128)
return GST_FLOW_OK; return GST_FLOW_OK;
}
g_assert (tag->v1tag_size == 0); g_assert (tag->v1tag_size == 0);
tag->v1tag_size = id3_tag_query (GST_BUFFER_DATA (tag->buffer), tag->v1tag_size = id3_tag_query (GST_BUFFER_DATA (buffer),
GST_BUFFER_SIZE (tag->buffer)); GST_BUFFER_SIZE (buffer));
if (tag->v1tag_size == 128) { if (tag->v1tag_size == 128) {
GstTagList *newtag; GstTagList *newtag;
newtag = gst_tag_list_new_from_id3v1 (GST_BUFFER_DATA (tag->buffer)); newtag = gst_tag_list_new_from_id3v1 (GST_BUFFER_DATA (buffer));
GST_LOG_OBJECT (tag, "have read ID3v1 tag"); GST_LOG_OBJECT (tag, "have read ID3v1 tag");
if (GST_BUFFER_OFFSET_IS_VALID (buffer))
tag->v1tag_offset = GST_BUFFER_OFFSET (buffer);
else
tag->v1tag_offset = G_MAXUINT64;
if (newtag) { if (newtag) {
if (tag->parsed_tags) { if (tag->parsed_tags) {
/* FIXME: use append/prepend here ? */ /* FIXME: use append/prepend here ? */
@ -1175,15 +1182,15 @@ gst_id3_tag_chain (GstPad * pad, GstBuffer * buffer)
GST_WARNING_OBJECT (tag, "bad non-ID3v1 tag at end of file"); GST_WARNING_OBJECT (tag, "bad non-ID3v1 tag at end of file");
} else { } else {
GST_LOG_OBJECT (tag, "no ID3v1 tag (%" G_GUINT64_FORMAT ")", GST_LOG_OBJECT (tag, "no ID3v1 tag (%" G_GUINT64_FORMAT ")",
GST_BUFFER_OFFSET (tag->buffer)); GST_BUFFER_OFFSET (buffer));
tag->v1tag_offset = G_MAXUINT64; tag->v1tag_offset = G_MAXUINT64;
} }
} }
gst_buffer_unref (tag->buffer); gst_buffer_unref (buffer);
tag->buffer = NULL;
if (tag->parse_mode != GST_ID3_TAG_PARSE_ANY) { 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 (offset %d)",
tag->v2tag_size);
gst_id3_tag_set_state (tag, GST_ID3_TAG_STATE_SEEKING_TO_NORMAL); gst_id3_tag_set_state (tag, GST_ID3_TAG_STATE_SEEKING_TO_NORMAL);
if (!gst_pad_push_event (tag->sinkpad, if (!gst_pad_push_event (tag->sinkpad,
gst_event_new_seek (1.0, GST_FORMAT_BYTES, GST_SEEK_FLAG_FLUSH, gst_event_new_seek (1.0, GST_FORMAT_BYTES, GST_SEEK_FLAG_FLUSH,
@ -1197,37 +1204,35 @@ gst_id3_tag_chain (GstPad * pad, GstBuffer * buffer)
/* set eos, we're done parsing tags */ /* set eos, we're done parsing tags */
GST_LOG_OBJECT (tag, "Finished reading ID3v1 tag"); GST_LOG_OBJECT (tag, "Finished reading ID3v1 tag");
gst_id3_tag_set_state (tag, GST_ID3_TAG_STATE_NORMAL_START); gst_id3_tag_set_state (tag, GST_ID3_TAG_STATE_NORMAL_START);
//gst_element_set_eos (GST_ELEMENT (tag));
gst_pad_push_event (tag->srcpad, gst_event_new_eos ()); gst_pad_push_event (tag->srcpad, gst_event_new_eos ());
} }
return GST_FLOW_OK; return GST_FLOW_OK;
case GST_ID3_TAG_STATE_READING_V2_TAG: case GST_ID3_TAG_STATE_READING_V2_TAG:
if (tag->buffer) { if (GST_BUFFER_SIZE (buffer) < 10) {
GstBuffer *temp;
temp = gst_buffer_merge (tag->buffer, buffer);
gst_buffer_unref (tag->buffer);
tag->buffer = temp;
gst_buffer_unref (buffer);
} else {
tag->buffer = buffer; tag->buffer = buffer;
}
if (GST_BUFFER_SIZE (tag->buffer) < 10)
return GST_FLOW_OK; return GST_FLOW_OK;
}
if (tag->v2tag_size == 0) { if (tag->v2tag_size == 0) {
tag->v2tag_size = id3_tag_query (GST_BUFFER_DATA (tag->buffer), tag->v2tag_size = id3_tag_query (GST_BUFFER_DATA (buffer),
GST_BUFFER_SIZE (tag->buffer)); GST_BUFFER_SIZE (buffer));
/* no footers supported */ /* no footers supported */
if (tag->v2tag_size < 0) if (tag->v2tag_size < 0)
tag->v2tag_size = 0; tag->v2tag_size = 0;
} }
if (GST_BUFFER_SIZE (tag->buffer) < tag->v2tag_size + ID3_TYPE_FIND_SIZE) /* Collect a large enough chunk to read the tag */
if (GST_BUFFER_SIZE (buffer) < tag->v2tag_size) {
GST_DEBUG_OBJECT (tag,
"Not enough data to read ID3v2. Need %d have %d, waiting for more",
tag->v2tag_size, GST_BUFFER_SIZE (buffer));
tag->buffer = buffer;
return GST_FLOW_OK; return GST_FLOW_OK;
}
if (tag->v2tag_size != 0) { if (tag->v2tag_size != 0) {
struct id3_tag *v2tag; struct id3_tag *v2tag;
v2tag = id3_tag_parse (GST_BUFFER_DATA (tag->buffer), v2tag = id3_tag_parse (GST_BUFFER_DATA (buffer),
GST_BUFFER_SIZE (tag->buffer)); GST_BUFFER_SIZE (buffer));
if (v2tag) { if (v2tag) {
GstTagList *list; GstTagList *list;
@ -1248,8 +1253,7 @@ gst_id3_tag_chain (GstPad * pad, GstBuffer * buffer)
if (gst_pad_push_event (tag->sinkpad, if (gst_pad_push_event (tag->sinkpad,
gst_event_new_seek (1.0, GST_FORMAT_BYTES, GST_SEEK_FLAG_FLUSH, gst_event_new_seek (1.0, GST_FORMAT_BYTES, GST_SEEK_FLAG_FLUSH,
GST_SEEK_TYPE_END, -128, GST_SEEK_TYPE_NONE, 0))) { GST_SEEK_TYPE_END, -128, GST_SEEK_TYPE_NONE, 0))) {
gst_buffer_unref (tag->buffer); gst_buffer_unref (buffer);
tag->buffer = NULL;
return GST_FLOW_OK; return GST_FLOW_OK;
} else { } else {
GST_DEBUG_OBJECT (tag, "Can't seek to read ID3v1 tag"); GST_DEBUG_OBJECT (tag, "Can't seek to read ID3v1 tag");
@ -1259,30 +1263,48 @@ gst_id3_tag_chain (GstPad * pad, GstBuffer * buffer)
GST_LOG_OBJECT (tag, GST_LOG_OBJECT (tag,
"removing first %ld bytes, because they're the ID3v2 tag", "removing first %ld bytes, because they're the ID3v2 tag",
tag->v2tag_size); tag->v2tag_size);
buffer = temp =
gst_buffer_create_sub (tag->buffer, tag->v2tag_size, gst_buffer_create_sub (buffer, tag->v2tag_size,
GST_BUFFER_SIZE (tag->buffer) - tag->v2tag_size); GST_BUFFER_SIZE (buffer) - tag->v2tag_size);
/* the offsets will be corrected further down, we just copy them */ /* the offsets will be corrected further down, we just copy them */
if (GST_BUFFER_OFFSET_IS_VALID (tag->buffer)) if (GST_BUFFER_OFFSET_IS_VALID (buffer))
GST_BUFFER_OFFSET (buffer) = GST_BUFFER_OFFSET (temp) = GST_BUFFER_OFFSET (buffer) + tag->v2tag_size;
GST_BUFFER_OFFSET (tag->buffer) + tag->v2tag_size; if (GST_BUFFER_OFFSET_END_IS_VALID (buffer))
if (GST_BUFFER_OFFSET_END_IS_VALID (tag->buffer)) GST_BUFFER_OFFSET_END (temp) =
GST_BUFFER_OFFSET_END (buffer) = GST_BUFFER_OFFSET_END (buffer) + tag->v2tag_size;
GST_BUFFER_OFFSET_END (tag->buffer) + tag->v2tag_size;
gst_buffer_unref (tag->buffer); gst_buffer_unref (buffer);
tag->buffer = NULL; buffer = temp;
gst_id3_tag_set_state (tag, GST_ID3_TAG_STATE_NORMAL_START); gst_id3_tag_set_state (tag, GST_ID3_TAG_STATE_NORMAL_START);
/* fall through */ /* fall through */
case GST_ID3_TAG_STATE_NORMAL_START: case GST_ID3_TAG_STATE_NORMAL_START:
g_assert (tag->buffer == NULL); if (!IS_MUXER (tag) && (tag->found_caps == NULL)) {
/* Don't do caps nego until we have at least ID3_TYPE_FIND_SIZE bytes */
if (!IS_MUXER (tag) && (tag->found_caps == NULL)) if (GST_BUFFER_SIZE (buffer) < ID3_TYPE_FIND_MIN_SIZE) {
if (!gst_id3_tag_do_caps_nego (tag, buffer)) { GST_DEBUG_OBJECT (tag,
gst_buffer_unref (buffer); "Not enough data (%d) for typefind, waiting for more",
GST_BUFFER_SIZE (buffer));
tag->buffer = buffer;
return GST_FLOW_OK; return GST_FLOW_OK;
} }
if (!gst_id3_tag_do_caps_nego (tag, buffer)) {
if (GST_BUFFER_SIZE (buffer) < ID3_TYPE_FIND_MAX_SIZE) {
/* Just break for more */
tag->buffer = buffer;
return GST_FLOW_OK;
}
/* We failed typefind */
GST_ELEMENT_ERROR (tag, CORE, CAPS, (NULL), ("no caps found"));
gst_buffer_unref (buffer);
return GST_FLOW_ERROR;
}
}
g_print ("Found type with size %u\n", GST_BUFFER_SIZE (buffer));
/* If we didn't get a segment event to pass on, someone /* If we didn't get a segment event to pass on, someone
* downstream is going to complain */ * downstream is going to complain */
if (tag->segment != NULL) { if (tag->segment != NULL) {
@ -1328,16 +1350,16 @@ gst_id3_tag_chain (GstPad * pad, GstBuffer * buffer)
case GST_ID3_TAG_STATE_NORMAL: case GST_ID3_TAG_STATE_NORMAL:
if (tag->parse_mode == GST_ID3_TAG_PARSE_ANY) { if (tag->parse_mode == GST_ID3_TAG_PARSE_ANY) {
gst_buffer_unref (buffer); gst_buffer_unref (buffer);
//gst_element_set_eos (GST_ELEMENT (tag));
gst_pad_push_event (tag->srcpad, gst_event_new_eos ()); gst_pad_push_event (tag->srcpad, gst_event_new_eos ());
} else { } else {
if (GST_BUFFER_OFFSET_IS_VALID (buffer)) { if (GST_BUFFER_OFFSET_IS_VALID (buffer)) {
if (buffer->offset >= tag->v1tag_offset) { if (GST_BUFFER_OFFSET (buffer) >= tag->v1tag_offset) {
gst_buffer_unref (buffer); gst_buffer_unref (buffer);
return GST_FLOW_OK; return GST_FLOW_OK;
} else if (buffer->offset + buffer->size > tag->v1tag_offset) { } else if (GST_BUFFER_OFFSET (buffer) + GST_BUFFER_SIZE (buffer) >
tag->v1tag_offset) {
GstBuffer *sub = gst_buffer_create_sub (buffer, 0, GstBuffer *sub = gst_buffer_create_sub (buffer, 0,
buffer->size - 128); GST_BUFFER_SIZE (buffer) - 128);
gst_buffer_unref (buffer); gst_buffer_unref (buffer);
buffer = sub; buffer = sub;
@ -1431,8 +1453,6 @@ plugin_init (GstPlugin * plugin)
if (!gst_element_register (plugin, "mad", GST_RANK_SECONDARY, if (!gst_element_register (plugin, "mad", GST_RANK_SECONDARY,
gst_mad_get_type ()) gst_mad_get_type ())
|| !gst_element_register (plugin, "id3demux", GST_RANK_PRIMARY,
gst_id3_tag_get_type (GST_ID3_TAG_PARSE_DEMUX))
|| !gst_element_register (plugin, "id3mux", GST_RANK_NONE, /* removed for spider */ || !gst_element_register (plugin, "id3mux", GST_RANK_NONE, /* removed for spider */
gst_id3_tag_get_type (GST_ID3_TAG_PARSE_MUX))) { gst_id3_tag_get_type (GST_ID3_TAG_PARSE_MUX))) {
return FALSE; return FALSE;

View File

@ -383,6 +383,7 @@ gst_mad_dispose (GObject * object)
G_OBJECT_CLASS (parent_class)->dispose (object); G_OBJECT_CLASS (parent_class)->dispose (object);
g_free (mad->tempbuffer); g_free (mad->tempbuffer);
mad->tempbuffer = NULL;
} }
static void static void