souphttpsrc: reduce reading latency by using non-blocking read
[platform/upstream/gst-plugins-good.git] / ext / taglib / gstid3v2mux.cc
index cc307aa..3ec9116 100644 (file)
@@ -14,8 +14,8 @@
  *
  * 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.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
  */
 
 /**
  * <refsect2>
  * <title>Example pipelines</title>
  * |[
- * gst-launch -v filesrc location=foo.ogg ! decodebin ! audioconvert ! lame ! id3v2mux ! filesink location=foo.mp3
+ * gst-launch-1.0 -v filesrc location=foo.ogg ! decodebin ! audioconvert ! lame ! id3v2mux ! filesink location=foo.mp3
  * ]| A pipeline that transcodes a file from Ogg/Vorbis to mp3 format with an
  * ID3v2 that contains the same as the the Ogg/Vorbis file. Make sure the
  * Ogg/Vorbis file actually has comments to preserve.
  * |[
- * gst-launch -m filesrc location=foo.mp3 ! id3demux ! fakesink silent=TRUE 2&gt; /dev/null | grep taglist
+ * gst-launch-1.0 -m filesrc location=foo.mp3 ! id3demux ! fakesink silent=TRUE 2&gt; /dev/null | grep taglist
  * ]| Verify that tags have been written.
  * </refsect2>
  */
@@ -72,22 +72,32 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS ("application/x-id3"));
 
+static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
+    GST_PAD_SINK,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("ANY"));
 
-GST_BOILERPLATE (GstId3v2Mux, gst_id3v2_mux, GstTagLibMux,
-    GST_TYPE_TAG_LIB_MUX);
+G_DEFINE_TYPE (GstId3v2Mux, gst_id3v2_mux, GST_TYPE_TAG_MUX);
 
-static GstBuffer *gst_id3v2_mux_render_tag (GstTagLibMux * mux,
-    GstTagList * taglist);
+static GstBuffer *gst_id3v2_mux_render_tag (GstTagMux * mux,
+    const GstTagList * taglist);
+static GstBuffer *gst_id3v2_mux_render_end_tag (GstTagMux * mux,
+    const GstTagList * taglist);
 
 static void
-gst_id3v2_mux_base_init (gpointer g_class)
+gst_id3v2_mux_class_init (GstId3v2MuxClass * klass)
 {
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_template));
+  GST_TAG_MUX_CLASS (klass)->render_start_tag =
+      GST_DEBUG_FUNCPTR (gst_id3v2_mux_render_tag);
+  GST_TAG_MUX_CLASS (klass)->render_end_tag =
+      GST_DEBUG_FUNCPTR (gst_id3v2_mux_render_end_tag);
 
-  gst_element_class_set_details_simple (element_class,
+  gst_element_class_add_static_pad_template (element_class, &sink_template);
+  gst_element_class_add_static_pad_template (element_class, &src_template);
+
+  gst_element_class_set_static_metadata (element_class,
       "TagLib-based ID3v2 Muxer", "Formatter/Metadata",
       "Adds an ID3v2 header to the beginning of MP3 files using taglib",
       "Christophe Fergeau <teuf@gnome.org>");
@@ -97,14 +107,7 @@ gst_id3v2_mux_base_init (gpointer g_class)
 }
 
 static void
-gst_id3v2_mux_class_init (GstId3v2MuxClass * klass)
-{
-  GST_TAG_LIB_MUX_CLASS (klass)->render_tag =
-      GST_DEBUG_FUNCPTR (gst_id3v2_mux_render_tag);
-}
-
-static void
-gst_id3v2_mux_init (GstId3v2Mux * id3v2mux, GstId3v2MuxClass * id3v2mux_class)
+gst_id3v2_mux_init (GstId3v2Mux * id3v2mux)
 {
   /* nothing to do */
 }
@@ -366,25 +369,30 @@ add_id3v2frame_tag (ID3v2::Tag * id3v2tag, const GstTagList * list,
     ID3v2::Frame * frame;
     const GValue *val;
     GstBuffer *buf;
+    GstSample *sample;
 
     val = gst_tag_list_get_value_index (list, tag, i);
-    buf = (GstBuffer *) g_value_get_boxed (val);
+    sample = (GstSample *) g_value_get_boxed (val);
 
-    if (buf && GST_BUFFER_CAPS (buf)) {
+    if (sample && (buf = gst_sample_get_buffer (sample)) &&
+        gst_sample_get_caps (sample)) {
       GstStructure *s;
       gint version = 0;
 
-      s = gst_caps_get_structure (GST_BUFFER_CAPS (buf), 0);
+      s = gst_caps_get_structure (gst_sample_get_caps (sample), 0);
       if (s && gst_structure_get_int (s, "version", &version) && version > 0) {
-        ByteVector bytes ((char *) GST_BUFFER_DATA (buf),
-            GST_BUFFER_SIZE (buf));
+        GstMapInfo map;
 
-        GST_DEBUG ("Injecting ID3v2.%u frame %u/%u of length %u and type %"
-            GST_PTR_FORMAT, version, i, num_tags, GST_BUFFER_SIZE (buf), s);
+        gst_buffer_map (buf, &map, GST_MAP_READ);
+        GST_DEBUG ("Injecting ID3v2.%u frame %u/%u of length %" G_GSIZE_FORMAT " and type %"
+            GST_PTR_FORMAT, version, i, num_tags, map.size, s);
 
-        frame = factory->createFrame (bytes, (TagLib::uint) version);
+        frame = factory->createFrame (ByteVector ((const char *) map.data,
+                map.size), (TagLib::uint) version);
         if (frame)
           id3v2tag->addFrame (frame);
+
+        gst_buffer_unmap (buf, &map);
       }
     }
   }
@@ -398,52 +406,79 @@ add_image_tag (ID3v2::Tag * id3v2tag, const GstTagList * list,
 
   for (n = 0; n < num_tags; ++n) {
     const GValue *val;
+    GstSample *sample;
     GstBuffer *image;
 
     GST_DEBUG ("image %u/%u", n + 1, num_tags);
 
     val = gst_tag_list_get_value_index (list, tag, n);
-    image = (GstBuffer *) g_value_get_boxed (val);
+    sample = (GstSample *) g_value_get_boxed (val);
 
-    if (GST_IS_BUFFER (image) && GST_BUFFER_SIZE (image) > 0 &&
-        GST_BUFFER_CAPS (image) != NULL &&
-        !gst_caps_is_empty (GST_BUFFER_CAPS (image))) {
+    if (GST_IS_SAMPLE (sample) && (image = gst_sample_get_buffer (sample)) &&
+        GST_IS_BUFFER (image) && gst_buffer_get_size (image) > 0 &&
+        gst_sample_get_caps (sample) != NULL &&
+        !gst_caps_is_empty (gst_sample_get_caps (sample))) {
       const gchar *mime_type;
       GstStructure *s;
 
-      s = gst_caps_get_structure (GST_BUFFER_CAPS (image), 0);
+      s = gst_caps_get_structure (gst_sample_get_caps (sample), 0);
       mime_type = gst_structure_get_name (s);
       if (mime_type != NULL) {
         ID3v2::AttachedPictureFrame * frame;
-        const gchar *desc;
+        const gchar *desc = NULL;
+        GstMapInfo map;
+        const GstStructure *info_struct;
+
+        info_struct = gst_sample_get_info (sample);
+        if (!info_struct
+            || !gst_structure_has_name (info_struct, "GstTagImageInfo"))
+          info_struct = NULL;
 
         if (strcmp (mime_type, "text/uri-list") == 0)
           mime_type = "-->";
 
         frame = new ID3v2::AttachedPictureFrame ();
 
-        GST_DEBUG ("Attaching picture of %u bytes and mime type %s",
-            GST_BUFFER_SIZE (image), mime_type);
+        gst_buffer_map (image, &map, GST_MAP_READ);
+
+        GST_DEBUG ("Attaching picture of %" G_GSIZE_FORMAT " bytes and mime type %s",
+            map.size, mime_type);
 
         id3v2tag->addFrame (frame);
-        frame->setPicture (ByteVector ((const char *) GST_BUFFER_DATA (image),
-                GST_BUFFER_SIZE (image)));
+        frame->setPicture (ByteVector ((const char *) map.data, map.size));
         frame->setTextEncoding (String::UTF8);
         frame->setMimeType (mime_type);
 
-        desc = gst_structure_get_string (s, "image-description");
+        gst_buffer_unmap (image, &map);
+
+        if (info_struct)
+          desc = gst_structure_get_string (info_struct, "image-description");
+
         frame->setDescription ((desc) ? desc : "");
 
-        /* FIXME set image type properly from caps */
         if (strcmp (tag, GST_TAG_PREVIEW_IMAGE) == 0) {
           frame->setType (ID3v2::AttachedPictureFrame::FileIcon);
         } else {
-          frame->setType (ID3v2::AttachedPictureFrame::Other);
+          int image_type = ID3v2::AttachedPictureFrame::Other;
+
+          if (info_struct) {
+            if (gst_structure_get (info_struct, "image-type",
+                    GST_TYPE_TAG_IMAGE_TYPE, &image_type, NULL)) {
+              if (image_type > 0 && image_type <= 18) {
+                image_type += 2;
+              } else {
+                image_type = ID3v2::AttachedPictureFrame::Other;
+              }
+            }
+          }
+
+          frame->setType ((TagLib::ID3v2::AttachedPictureFrame::Type) image_type);
         }
       }
     } else {
-      GST_WARNING ("NULL image or no caps on image buffer (%p, caps=%"
-          GST_PTR_FORMAT ")", image, (image) ? GST_BUFFER_CAPS (image) : NULL);
+      GST_WARNING ("NULL image or no caps on image sample (%p, caps=%"
+          GST_PTR_FORMAT ")", sample,
+          (sample) ? gst_sample_get_caps (sample) : NULL);
     }
   }
 }
@@ -586,7 +621,7 @@ add_relative_volume_tag (ID3v2::Tag * id3v2tag, const GstTagList * list,
     frame->setIdentification ("album");
     GST_DEBUG ("adding album relative-volume frame");
   }
-  
+
   /* find the value for the paired tag (gain, if this is peak, and
    * vice versa).  if both tags exist, only write the frame when
    * we're processing the peak tag.
@@ -724,7 +759,7 @@ foreach_add_tag (const GstTagList * list, const gchar * tag, gpointer userdata)
 }
 
 static GstBuffer *
-gst_id3v2_mux_render_tag (GstTagLibMux * mux, GstTagList * taglist)
+gst_id3v2_mux_render_tag (GstTagMux * mux, const GstTagList * taglist)
 {
   ID3v2::Tag id3v2tag;
   ByteVector rendered_tag;
@@ -757,20 +792,13 @@ gst_id3v2_mux_render_tag (GstTagLibMux * mux, GstTagList * taglist)
 
   /* Create buffer with tag */
   buf = gst_buffer_new_and_alloc (tag_size);
-  memcpy (GST_BUFFER_DATA (buf), rendered_tag.data (), tag_size);
-  gst_buffer_set_caps (buf, GST_PAD_CAPS (mux->srcpad));
+  gst_buffer_fill (buf, 0, rendered_tag.data (), tag_size);
 
   return buf;
 }
 
-gboolean
-gst_id3v2_mux_plugin_init (GstPlugin * plugin)
+static GstBuffer *
+gst_id3v2_mux_render_end_tag (GstTagMux * mux, const GstTagList * taglist)
 {
-  if (!gst_element_register (plugin, "id3v2mux", GST_RANK_NONE,
-          GST_TYPE_ID3V2_MUX))
-    return FALSE;
-
-  gst_tag_register_musicbrainz_tags ();
-
-  return TRUE;
+  return NULL;
 }