]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/gst-plugins-ugly0-10.git/commitdiff
ext/mad/gstid3tag.c: Fix typefinding in id3demux, and then remove it in favour of...
authorJan Schmidt <thaytan@mad.scientist.com>
Sun, 18 Dec 2005 15:08:15 +0000 (15:08 +0000)
committerJan Schmidt <thaytan@mad.scientist.com>
Sun, 18 Dec 2005 15:08:15 +0000 (15:08 +0000)
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.

ChangeLog
ext/mad/gstid3tag.c
ext/mad/gstmad.c

index 401e406b2cacf46f7b1813060d20688af0e3cb3f..924ce3f18723d3c46d36209688858bb1f8361141 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
 
        * gst/asfdemux/gstasfmux.c: (gst_asfmux_file_start):
index 9beb58e2a1f49da0abd2899e109c975f82d0a353..093429a02778d47b715cf1d35fe824e13d64fc1c 100644 (file)
@@ -27,7 +27,9 @@
 #include <string.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);
 #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);
   if (find.best_probability > 0) {
     return find.caps;
-  } else {
-    GST_ELEMENT_ERROR (tag, CORE, CAPS, (NULL), ("no caps found"));
-    return NULL;
   }
+
+  return NULL;
 }
+
 static gboolean
 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) {
       return FALSE;
     }
+    GST_DEBUG_OBJECT (tag, "Found contained data caps %" GST_PTR_FORMAT,
+        tag->found_caps);
   }
   if (tag->srcpad == NULL) {
     gst_id3_tag_add_src_pad (tag);
@@ -1126,9 +1130,15 @@ static GstFlowReturn
 gst_id3_tag_chain (GstPad * pad, GstBuffer * buffer)
 {
   GstID3Tag *tag;
+  GstBuffer *temp;
 
   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) {
     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);
       return GST_FLOW_OK;
     case GST_ID3_TAG_STATE_READING_V1_TAG:
-      if (tag->buffer) {
-        GstBuffer *temp;
-
-        temp = gst_buffer_merge (tag->buffer, buffer);
-        gst_buffer_unref (tag->buffer);
-        tag->buffer = temp;
-        gst_buffer_unref (buffer);
-      } else {
+      if (GST_BUFFER_SIZE (buffer) < 128) {
         tag->buffer = buffer;
-        tag->v1tag_offset = buffer->offset;
-      }
-      if (GST_BUFFER_SIZE (tag->buffer) < 128)
         return GST_FLOW_OK;
+      }
+
       g_assert (tag->v1tag_size == 0);
-      tag->v1tag_size = id3_tag_query (GST_BUFFER_DATA (tag->buffer),
-          GST_BUFFER_SIZE (tag->buffer));
+      tag->v1tag_size = id3_tag_query (GST_BUFFER_DATA (buffer),
+          GST_BUFFER_SIZE (buffer));
       if (tag->v1tag_size == 128) {
         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");
+        if (GST_BUFFER_OFFSET_IS_VALID (buffer))
+          tag->v1tag_offset = GST_BUFFER_OFFSET (buffer);
+        else
+          tag->v1tag_offset = G_MAXUINT64;
+
         if (newtag) {
           if (tag->parsed_tags) {
             /* 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");
         } else {
           GST_LOG_OBJECT (tag, "no ID3v1 tag (%" G_GUINT64_FORMAT ")",
-              GST_BUFFER_OFFSET (tag->buffer));
+              GST_BUFFER_OFFSET (buffer));
           tag->v1tag_offset = G_MAXUINT64;
         }
       }
-      gst_buffer_unref (tag->buffer);
-      tag->buffer = NULL;
+      gst_buffer_unref (buffer);
       if (tag->parse_mode != GST_ID3_TAG_PARSE_ANY) {
         /* 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);
         if (!gst_pad_push_event (tag->sinkpad,
                 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 */
         GST_LOG_OBJECT (tag, "Finished reading ID3v1 tag");
         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 ());
       }
       return GST_FLOW_OK;
     case GST_ID3_TAG_STATE_READING_V2_TAG:
-      if (tag->buffer) {
-        GstBuffer *temp;
-
-        temp = gst_buffer_merge (tag->buffer, buffer);
-        gst_buffer_unref (tag->buffer);
-        tag->buffer = temp;
-        gst_buffer_unref (buffer);
-      } else {
+      if (GST_BUFFER_SIZE (buffer) < 10) {
         tag->buffer = buffer;
-      }
-      if (GST_BUFFER_SIZE (tag->buffer) < 10)
         return GST_FLOW_OK;
+      }
       if (tag->v2tag_size == 0) {
-        tag->v2tag_size = id3_tag_query (GST_BUFFER_DATA (tag->buffer),
-            GST_BUFFER_SIZE (tag->buffer));
+        tag->v2tag_size = id3_tag_query (GST_BUFFER_DATA (buffer),
+            GST_BUFFER_SIZE (buffer));
         /* no footers supported */
         if (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;
+      }
+
       if (tag->v2tag_size != 0) {
         struct id3_tag *v2tag;
 
-        v2tag = id3_tag_parse (GST_BUFFER_DATA (tag->buffer),
-            GST_BUFFER_SIZE (tag->buffer));
+        v2tag = id3_tag_parse (GST_BUFFER_DATA (buffer),
+            GST_BUFFER_SIZE (buffer));
         if (v2tag) {
           GstTagList *list;
 
@@ -1248,8 +1253,7 @@ gst_id3_tag_chain (GstPad * pad, GstBuffer * buffer)
       if (gst_pad_push_event (tag->sinkpad,
               gst_event_new_seek (1.0, GST_FORMAT_BYTES, GST_SEEK_FLAG_FLUSH,
                   GST_SEEK_TYPE_END, -128, GST_SEEK_TYPE_NONE, 0))) {
-        gst_buffer_unref (tag->buffer);
-        tag->buffer = NULL;
+        gst_buffer_unref (buffer);
         return GST_FLOW_OK;
       } else {
         GST_DEBUG_OBJECT (tag, "Can't seek to read ID3v1 tag");
@@ -1259,29 +1263,47 @@ gst_id3_tag_chain (GstPad * pad, GstBuffer * buffer)
       GST_LOG_OBJECT (tag,
           "removing first %ld bytes, because they're the ID3v2 tag",
           tag->v2tag_size);
-      buffer =
-          gst_buffer_create_sub (tag->buffer, tag->v2tag_size,
-          GST_BUFFER_SIZE (tag->buffer) - tag->v2tag_size);
+      temp =
+          gst_buffer_create_sub (buffer, tag->v2tag_size,
+          GST_BUFFER_SIZE (buffer) - tag->v2tag_size);
       /* the offsets will be corrected further down, we just copy them */
-      if (GST_BUFFER_OFFSET_IS_VALID (tag->buffer))
-        GST_BUFFER_OFFSET (buffer) =
-            GST_BUFFER_OFFSET (tag->buffer) + tag->v2tag_size;
-      if (GST_BUFFER_OFFSET_END_IS_VALID (tag->buffer))
-        GST_BUFFER_OFFSET_END (buffer) =
-            GST_BUFFER_OFFSET_END (tag->buffer) + tag->v2tag_size;
-      gst_buffer_unref (tag->buffer);
-      tag->buffer = NULL;
+      if (GST_BUFFER_OFFSET_IS_VALID (buffer))
+        GST_BUFFER_OFFSET (temp) = GST_BUFFER_OFFSET (buffer) + tag->v2tag_size;
+      if (GST_BUFFER_OFFSET_END_IS_VALID (buffer))
+        GST_BUFFER_OFFSET_END (temp) =
+            GST_BUFFER_OFFSET_END (buffer) + tag->v2tag_size;
+
+      gst_buffer_unref (buffer);
+      buffer = temp;
 
       gst_id3_tag_set_state (tag, GST_ID3_TAG_STATE_NORMAL_START);
       /* fall through */
     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 (GST_BUFFER_SIZE (buffer) < ID3_TYPE_FIND_MIN_SIZE) {
+          GST_DEBUG_OBJECT (tag,
+              "Not enough data (%d) for typefind, waiting for more",
+              GST_BUFFER_SIZE (buffer));
+          tag->buffer = buffer;
+          return GST_FLOW_OK;
+        }
 
-      if (!IS_MUXER (tag) && (tag->found_caps == NULL))
         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_OK;
+          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
        * downstream is going to complain */
@@ -1328,16 +1350,16 @@ gst_id3_tag_chain (GstPad * pad, GstBuffer * buffer)
     case GST_ID3_TAG_STATE_NORMAL:
       if (tag->parse_mode == GST_ID3_TAG_PARSE_ANY) {
         gst_buffer_unref (buffer);
-        //gst_element_set_eos (GST_ELEMENT (tag));
         gst_pad_push_event (tag->srcpad, gst_event_new_eos ());
       } else {
         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);
             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,
-                buffer->size - 128);
+                GST_BUFFER_SIZE (buffer) - 128);
 
             gst_buffer_unref (buffer);
             buffer = sub;
@@ -1431,8 +1453,6 @@ plugin_init (GstPlugin * plugin)
 
   if (!gst_element_register (plugin, "mad", GST_RANK_SECONDARY,
           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_id3_tag_get_type (GST_ID3_TAG_PARSE_MUX))) {
     return FALSE;
index 9128243581d8eca7b4049cfa3b302ed2ab3d606b..f9f28949f922b55597eb1abd31e47c8248e1f735 100644 (file)
@@ -383,6 +383,7 @@ gst_mad_dispose (GObject * object)
   G_OBJECT_CLASS (parent_class)->dispose (object);
 
   g_free (mad->tempbuffer);
+  mad->tempbuffer = NULL;
 }
 
 static void