taglib: port to 0.11

This commit is contained in:
Mark Nauwelaerts 2012-02-01 18:01:27 +01:00
parent 0f3b7b010e
commit da0cdc7713
5 changed files with 96 additions and 105 deletions

View file

@ -316,7 +316,7 @@ GST_PLUGINS_NONPORTED="deinterlace interleave flx goom2k1 \
videobox \ videobox \
cairo cairo_gobject dv1394 gdk_pixbuf libdv \ cairo cairo_gobject dv1394 gdk_pixbuf libdv \
oss oss4 shout2 \ oss oss4 shout2 \
taglib wavpack \ wavpack \
osx_video osx_audio " osx_video osx_audio "
AC_SUBST(GST_PLUGINS_NONPORTED) AC_SUBST(GST_PLUGINS_NONPORTED)

View file

@ -64,16 +64,18 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS ("application/x-apetag")); GST_STATIC_CAPS ("application/x-apetag"));
GST_BOILERPLATE (GstApev2Mux, gst_apev2_mux, GstTagLibMux, G_DEFINE_TYPE (GstApev2Mux, gst_apev2_mux, GST_TYPE_TAG_LIB_MUX);
GST_TYPE_TAG_LIB_MUX);
static GstBuffer *gst_apev2_mux_render_tag (GstTagLibMux * mux, static GstBuffer *gst_apev2_mux_render_tag (GstTagLibMux * mux,
GstTagList * taglist); GstTagList * taglist);
static void static void
gst_apev2_mux_base_init (gpointer g_class) gst_apev2_mux_class_init (GstApev2MuxClass * klass)
{ {
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GST_TAG_LIB_MUX_CLASS (klass)->render_tag =
GST_DEBUG_FUNCPTR (gst_apev2_mux_render_tag);
gst_element_class_add_pad_template (element_class, gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_template)); gst_static_pad_template_get (&src_template));
@ -88,14 +90,7 @@ gst_apev2_mux_base_init (gpointer g_class)
} }
static void static void
gst_apev2_mux_class_init (GstApev2MuxClass * klass) gst_apev2_mux_init (GstApev2Mux * apev2mux)
{
GST_TAG_LIB_MUX_CLASS (klass)->render_tag =
GST_DEBUG_FUNCPTR (gst_apev2_mux_render_tag);
}
static void
gst_apev2_mux_init (GstApev2Mux * apev2mux, GstApev2MuxClass * apev2mux_class)
{ {
/* nothing to do */ /* nothing to do */
} }
@ -357,8 +352,7 @@ gst_apev2_mux_render_tag (GstTagLibMux * mux, GstTagList * taglist)
/* Create buffer with tag */ /* Create buffer with tag */
buf = gst_buffer_new_and_alloc (tag_size); buf = gst_buffer_new_and_alloc (tag_size);
memcpy (GST_BUFFER_DATA (buf), rendered_tag.data (), tag_size); gst_buffer_fill (buf, 0, rendered_tag.data (), tag_size);
gst_buffer_set_caps (buf, GST_PAD_CAPS (mux->srcpad));
return buf; return buf;
} }

View file

@ -73,16 +73,18 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
GST_STATIC_CAPS ("application/x-id3")); GST_STATIC_CAPS ("application/x-id3"));
GST_BOILERPLATE (GstId3v2Mux, gst_id3v2_mux, GstTagLibMux, G_DEFINE_TYPE (GstId3v2Mux, gst_id3v2_mux, GST_TYPE_TAG_LIB_MUX);
GST_TYPE_TAG_LIB_MUX);
static GstBuffer *gst_id3v2_mux_render_tag (GstTagLibMux * mux, static GstBuffer *gst_id3v2_mux_render_tag (GstTagLibMux * mux,
GstTagList * taglist); GstTagList * taglist);
static void 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_TAG_LIB_MUX_CLASS (klass)->render_tag =
GST_DEBUG_FUNCPTR (gst_id3v2_mux_render_tag);
gst_element_class_add_pad_template (element_class, gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_template)); gst_static_pad_template_get (&src_template));
@ -97,14 +99,7 @@ gst_id3v2_mux_base_init (gpointer g_class)
} }
static void static void
gst_id3v2_mux_class_init (GstId3v2MuxClass * klass) gst_id3v2_mux_init (GstId3v2Mux * id3v2mux)
{
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)
{ {
/* nothing to do */ /* nothing to do */
} }
@ -366,25 +361,30 @@ add_id3v2frame_tag (ID3v2::Tag * id3v2tag, const GstTagList * list,
ID3v2::Frame * frame; ID3v2::Frame * frame;
const GValue *val; const GValue *val;
GstBuffer *buf; GstBuffer *buf;
GstSample *sample;
val = gst_tag_list_get_value_index (list, tag, i); 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; GstStructure *s;
gint version = 0; 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) { if (s && gst_structure_get_int (s, "version", &version) && version > 0) {
ByteVector bytes ((char *) GST_BUFFER_DATA (buf), GstMapInfo map;
GST_BUFFER_SIZE (buf));
gst_buffer_map (buf, &map, GST_MAP_READ);
GST_DEBUG ("Injecting ID3v2.%u frame %u/%u of length %u and type %" 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_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) if (frame)
id3v2tag->addFrame (frame); id3v2tag->addFrame (frame);
gst_buffer_unmap (buf, &map);
} }
} }
} }
@ -398,39 +398,45 @@ add_image_tag (ID3v2::Tag * id3v2tag, const GstTagList * list,
for (n = 0; n < num_tags; ++n) { for (n = 0; n < num_tags; ++n) {
const GValue *val; const GValue *val;
GstSample *sample;
GstBuffer *image; GstBuffer *image;
GST_DEBUG ("image %u/%u", n + 1, num_tags); GST_DEBUG ("image %u/%u", n + 1, num_tags);
val = gst_tag_list_get_value_index (list, tag, n); 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 && if (GST_IS_SAMPLE (image) && (image = gst_sample_get_buffer (sample)) &&
GST_BUFFER_CAPS (image) != NULL && GST_IS_BUFFER (image) && gst_buffer_get_size (image) > 0 &&
!gst_caps_is_empty (GST_BUFFER_CAPS (image))) { gst_sample_get_caps (sample) != NULL &&
!gst_caps_is_empty (gst_sample_get_caps (sample))) {
const gchar *mime_type; const gchar *mime_type;
GstStructure *s; 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); mime_type = gst_structure_get_name (s);
if (mime_type != NULL) { if (mime_type != NULL) {
ID3v2::AttachedPictureFrame * frame; ID3v2::AttachedPictureFrame * frame;
const gchar *desc; const gchar *desc;
GstMapInfo map;
if (strcmp (mime_type, "text/uri-list") == 0) if (strcmp (mime_type, "text/uri-list") == 0)
mime_type = "-->"; mime_type = "-->";
frame = new ID3v2::AttachedPictureFrame (); frame = new ID3v2::AttachedPictureFrame ();
gst_buffer_map (image, &map, GST_MAP_READ);
GST_DEBUG ("Attaching picture of %u bytes and mime type %s", GST_DEBUG ("Attaching picture of %u bytes and mime type %s",
GST_BUFFER_SIZE (image), mime_type); map.size, mime_type);
id3v2tag->addFrame (frame); id3v2tag->addFrame (frame);
frame->setPicture (ByteVector ((const char *) GST_BUFFER_DATA (image), frame->setPicture (ByteVector ((const char *) map.data, map.size));
GST_BUFFER_SIZE (image)));
frame->setTextEncoding (String::UTF8); frame->setTextEncoding (String::UTF8);
frame->setMimeType (mime_type); frame->setMimeType (mime_type);
gst_buffer_unmap (image, &map);
desc = gst_structure_get_string (s, "image-description"); desc = gst_structure_get_string (s, "image-description");
frame->setDescription ((desc) ? desc : ""); frame->setDescription ((desc) ? desc : "");
@ -442,8 +448,9 @@ add_image_tag (ID3v2::Tag * id3v2tag, const GstTagList * list,
} }
} }
} else { } else {
GST_WARNING ("NULL image or no caps on image buffer (%p, caps=%" GST_WARNING ("NULL image or no caps on image sample (%p, caps=%"
GST_PTR_FORMAT ")", image, (image) ? GST_BUFFER_CAPS (image) : NULL); GST_PTR_FORMAT ")", sample,
(sample) ? gst_sample_get_caps (sample) : NULL);
} }
} }
} }
@ -757,8 +764,7 @@ gst_id3v2_mux_render_tag (GstTagLibMux * mux, GstTagList * taglist)
/* Create buffer with tag */ /* Create buffer with tag */
buf = gst_buffer_new_and_alloc (tag_size); buf = gst_buffer_new_and_alloc (tag_size);
memcpy (GST_BUFFER_DATA (buf), rendered_tag.data (), tag_size); gst_buffer_fill (buf, 0, rendered_tag.data (), tag_size);
gst_buffer_set_caps (buf, GST_PAD_CAPS (mux->srcpad));
return buf; return buf;
} }

View file

@ -38,27 +38,17 @@ GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS ("ANY")); GST_STATIC_CAPS ("ANY"));
static void
gst_tag_lib_mux_iface_init (GType taglib_type)
{
static const GInterfaceInfo tag_setter_info = {
NULL,
NULL,
NULL
};
g_type_add_interface_static (taglib_type, GST_TYPE_TAG_SETTER,
&tag_setter_info);
}
GST_BOILERPLATE_FULL (GstTagLibMux, gst_tag_lib_mux,
GstElement, GST_TYPE_ELEMENT, gst_tag_lib_mux_iface_init);
#define gst_tag_lib_mux_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstTagLibMux, gst_tag_lib_mux, GST_TYPE_ELEMENT,
G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL));
static GstStateChangeReturn static GstStateChangeReturn
gst_tag_lib_mux_change_state (GstElement * element, GstStateChange transition); gst_tag_lib_mux_change_state (GstElement * element, GstStateChange transition);
static GstFlowReturn gst_tag_lib_mux_chain (GstPad * pad, GstBuffer * buffer); static GstFlowReturn gst_tag_lib_mux_chain (GstPad * pad, GstObject * parent,
static gboolean gst_tag_lib_mux_sink_event (GstPad * pad, GstEvent * event); GstBuffer * buffer);
static gboolean gst_tag_lib_mux_sink_event (GstPad * pad, GstObject * parent,
GstEvent * event);
static void static void
gst_tag_lib_mux_finalize (GObject * obj) gst_tag_lib_mux_finalize (GObject * obj)
@ -78,18 +68,6 @@ gst_tag_lib_mux_finalize (GObject * obj)
G_OBJECT_CLASS (parent_class)->finalize (obj); G_OBJECT_CLASS (parent_class)->finalize (obj);
} }
static void
gst_tag_lib_mux_base_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&gst_tag_lib_mux_sink_template));
GST_DEBUG_CATEGORY_INIT (gst_tag_lib_mux_debug, "taglibmux", 0,
"taglib-based muxer");
}
static void static void
gst_tag_lib_mux_class_init (GstTagLibMuxClass * klass) gst_tag_lib_mux_class_init (GstTagLibMuxClass * klass)
{ {
@ -102,11 +80,18 @@ gst_tag_lib_mux_class_init (GstTagLibMuxClass * klass)
gobject_class->finalize = gst_tag_lib_mux_finalize; gobject_class->finalize = gst_tag_lib_mux_finalize;
gstelement_class->change_state = gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_tag_lib_mux_change_state); GST_DEBUG_FUNCPTR (gst_tag_lib_mux_change_state);
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&gst_tag_lib_mux_sink_template));
GST_DEBUG_CATEGORY_INIT (gst_tag_lib_mux_debug, "taglibmux", 0,
"taglib-based muxer");
} }
static void static void
gst_tag_lib_mux_init (GstTagLibMux * mux, GstTagLibMuxClass * mux_class) gst_tag_lib_mux_init (GstTagLibMux * mux)
{ {
GstTagLibMuxClass *mux_class = GST_TAG_LIB_MUX_GET_CLASS (mux);
GstElementClass *element_klass = GST_ELEMENT_CLASS (mux_class); GstElementClass *element_klass = GST_ELEMENT_CLASS (mux_class);
GstPadTemplate *tmpl; GstPadTemplate *tmpl;
@ -141,6 +126,7 @@ gst_tag_lib_mux_render_tag (GstTagLibMux * mux)
const GstTagList *tagsetter_tags; const GstTagList *tagsetter_tags;
GstTagList *taglist; GstTagList *taglist;
GstEvent *event; GstEvent *event;
GstSegment segment;
tagsetter = GST_TAG_SETTER (mux); tagsetter = GST_TAG_SETTER (mux);
@ -165,13 +151,13 @@ gst_tag_lib_mux_render_tag (GstTagLibMux * mux)
if (buffer == NULL) if (buffer == NULL)
goto render_error; goto render_error;
mux->tag_size = GST_BUFFER_SIZE (buffer); mux->tag_size = gst_buffer_get_size (buffer);
GST_LOG_OBJECT (mux, "tag size = %" G_GSIZE_FORMAT " bytes", mux->tag_size); GST_LOG_OBJECT (mux, "tag size = %" G_GSIZE_FORMAT " bytes", mux->tag_size);
/* Send newsegment event from byte position 0, so the tag really gets /* Send newsegment event from byte position 0, so the tag really gets
* written to the start of the file, independent of the upstream segment */ * written to the start of the file, independent of the upstream segment */
gst_pad_push_event (mux->srcpad, gst_segment_init (&segment, GST_FORMAT_BYTES);
gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, 0, -1, 0)); gst_pad_push_event (mux->srcpad, gst_event_new_segment (&segment));
/* Send an event about the new tags to downstream elements */ /* Send an event about the new tags to downstream elements */
/* gst_event_new_tag takes ownership of the list, so no need to unref it */ /* gst_event_new_tag takes ownership of the list, so no need to unref it */
@ -201,36 +187,37 @@ static GstEvent *
gst_tag_lib_mux_adjust_event_offsets (GstTagLibMux * mux, gst_tag_lib_mux_adjust_event_offsets (GstTagLibMux * mux,
const GstEvent * newsegment_event) const GstEvent * newsegment_event)
{ {
GstFormat format;
gint64 start, stop, cur; gint64 start, stop, cur;
GstSegment segment;
gst_event_parse_new_segment ((GstEvent *) newsegment_event, NULL, NULL, gst_event_copy_segment ((GstEvent *) newsegment_event, &segment);
&format, &start, &stop, &cur);
g_assert (format == GST_FORMAT_BYTES); g_assert (segment.format == GST_FORMAT_BYTES);
if (start != -1) if (segment.start != -1)
start += mux->tag_size; start += mux->tag_size;
if (stop != -1) if (segment.stop != -1)
stop += mux->tag_size; stop += mux->tag_size;
if (cur != -1) if (segment.time != -1)
cur += mux->tag_size; cur += mux->tag_size;
GST_DEBUG_OBJECT (mux, "adjusting newsegment event offsets to start=%" GST_DEBUG_OBJECT (mux, "adjusting newsegment event offsets to start=%"
G_GINT64_FORMAT ", stop=%" G_GINT64_FORMAT ", cur=%" G_GINT64_FORMAT G_GUINT64_FORMAT ", stop=%" G_GUINT64_FORMAT ", cur=%" G_GUINT64_FORMAT
" (delta = +%" G_GSIZE_FORMAT ")", start, stop, cur, mux->tag_size); " (delta = +%" G_GSIZE_FORMAT ")",
segment.start, segment.stop, segment.time, mux->tag_size);
return gst_event_new_new_segment (TRUE, 1.0, format, start, stop, cur); return gst_event_new_segment (&segment);
} }
static GstFlowReturn static GstFlowReturn
gst_tag_lib_mux_chain (GstPad * pad, GstBuffer * buffer) gst_tag_lib_mux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{ {
GstTagLibMux *mux = GST_TAG_LIB_MUX (GST_OBJECT_PARENT (pad)); GstTagLibMux *mux = GST_TAG_LIB_MUX (parent);
if (mux->render_tag) { if (mux->render_tag) {
GstFlowReturn ret; GstFlowReturn ret;
GstBuffer *tag_buffer; GstBuffer *tag_buffer;
GstCaps *tcaps;
GST_INFO_OBJECT (mux, "Adding tags to stream"); GST_INFO_OBJECT (mux, "Adding tags to stream");
tag_buffer = gst_tag_lib_mux_render_tag (mux); tag_buffer = gst_tag_lib_mux_render_tag (mux);
@ -255,18 +242,22 @@ gst_tag_lib_mux_chain (GstPad * pad, GstBuffer * buffer)
} }
mux->render_tag = FALSE; mux->render_tag = FALSE;
/* we have data flow, so pad is active and caps can be set */
tcaps = gst_pad_get_pad_template_caps (mux->srcpad);
gst_pad_set_caps (mux->srcpad, tcaps);
gst_caps_unref (tcaps);
} }
buffer = gst_buffer_make_metadata_writable (buffer); buffer = gst_buffer_make_writable (buffer);
if (GST_BUFFER_OFFSET (buffer) != GST_BUFFER_OFFSET_NONE) { if (GST_BUFFER_OFFSET (buffer) != GST_BUFFER_OFFSET_NONE) {
GST_LOG_OBJECT (mux, "Adjusting buffer offset from %" G_GINT64_FORMAT GST_LOG_OBJECT (mux, "Adjusting buffer offset from %" G_GUINT64_FORMAT
" to %" G_GINT64_FORMAT, GST_BUFFER_OFFSET (buffer), " to %" G_GUINT64_FORMAT, GST_BUFFER_OFFSET (buffer),
GST_BUFFER_OFFSET (buffer) + mux->tag_size); GST_BUFFER_OFFSET (buffer) + mux->tag_size);
GST_BUFFER_OFFSET (buffer) += mux->tag_size; GST_BUFFER_OFFSET (buffer) += mux->tag_size;
} }
gst_buffer_set_caps (buffer, GST_PAD_CAPS (mux->srcpad));
return gst_pad_push (mux->srcpad, buffer); return gst_pad_push (mux->srcpad, buffer);
/* ERRORS */ /* ERRORS */
@ -278,12 +269,12 @@ no_tag_buffer:
} }
static gboolean static gboolean
gst_tag_lib_mux_sink_event (GstPad * pad, GstEvent * event) gst_tag_lib_mux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{ {
GstTagLibMux *mux; GstTagLibMux *mux;
gboolean result; gboolean result;
mux = GST_TAG_LIB_MUX (gst_pad_get_parent (pad)); mux = GST_TAG_LIB_MUX (parent);
result = FALSE; result = FALSE;
switch (GST_EVENT_TYPE (event)) { switch (GST_EVENT_TYPE (event)) {
@ -308,14 +299,14 @@ gst_tag_lib_mux_sink_event (GstPad * pad, GstEvent * event)
result = TRUE; result = TRUE;
break; break;
} }
case GST_EVENT_NEWSEGMENT:{ case GST_EVENT_SEGMENT:{
GstFormat fmt; const GstSegment *segment;
gst_event_parse_new_segment (event, NULL, NULL, &fmt, NULL, NULL, NULL); gst_event_parse_segment (event, &segment);
if (fmt != GST_FORMAT_BYTES) { if (segment->format != GST_FORMAT_BYTES) {
GST_WARNING_OBJECT (mux, "dropping newsegment event in %s format", GST_WARNING_OBJECT (mux, "dropping newsegment event in %s format",
gst_format_get_name (fmt)); gst_format_get_name (segment->format));
gst_event_unref (event); gst_event_unref (event);
break; break;
} }
@ -344,12 +335,10 @@ gst_tag_lib_mux_sink_event (GstPad * pad, GstEvent * event)
break; break;
} }
default: default:
result = gst_pad_event_default (pad, event); result = gst_pad_event_default (pad, parent, event);
break; break;
} }
gst_object_unref (mux);
return result; return result;
} }

View file

@ -60,6 +60,8 @@ struct _GstTagLibMuxClass {
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TAG_LIB_MUX)) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TAG_LIB_MUX))
#define GST_IS_TAG_LIB_MUX_CLASS(klass) \ #define GST_IS_TAG_LIB_MUX_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TAG_LIB_MUX)) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TAG_LIB_MUX))
#define GST_TAG_LIB_MUX_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_TAG_LIB_MUX, GstTagLibMuxClass))
/* Standard function returning type information. */ /* Standard function returning type information. */
GType gst_tag_lib_mux_get_type (void); GType gst_tag_lib_mux_get_type (void);