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:
parent
80d81b7e34
commit
16d1543b88
@ -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):
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user