diff --git a/configure.ac b/configure.ac index 1f6e5fafe8..51b5790cc9 100644 --- a/configure.ac +++ b/configure.ac @@ -316,7 +316,7 @@ GST_PLUGINS_NONPORTED="deinterlace interleave flx goom2k1 \ videobox \ cairo cairo_gobject dv1394 gdk_pixbuf libdv \ oss oss4 shout2 \ - taglib wavpack \ + wavpack \ osx_video osx_audio " AC_SUBST(GST_PLUGINS_NONPORTED) diff --git a/ext/taglib/gstapev2mux.cc b/ext/taglib/gstapev2mux.cc index 58206e61e0..2e7e1738e4 100644 --- a/ext/taglib/gstapev2mux.cc +++ b/ext/taglib/gstapev2mux.cc @@ -64,16 +64,18 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_ALWAYS, GST_STATIC_CAPS ("application/x-apetag")); -GST_BOILERPLATE (GstApev2Mux, gst_apev2_mux, GstTagLibMux, - GST_TYPE_TAG_LIB_MUX); +G_DEFINE_TYPE (GstApev2Mux, gst_apev2_mux, GST_TYPE_TAG_LIB_MUX); static GstBuffer *gst_apev2_mux_render_tag (GstTagLibMux * mux, GstTagList * taglist); 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_static_pad_template_get (&src_template)); @@ -88,14 +90,7 @@ gst_apev2_mux_base_init (gpointer g_class) } static void -gst_apev2_mux_class_init (GstApev2MuxClass * klass) -{ - 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) +gst_apev2_mux_init (GstApev2Mux * apev2mux) { /* nothing to do */ } @@ -357,8 +352,7 @@ gst_apev2_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; } diff --git a/ext/taglib/gstid3v2mux.cc b/ext/taglib/gstid3v2mux.cc index cc307aa0fd..9b33b94b04 100644 --- a/ext/taglib/gstid3v2mux.cc +++ b/ext/taglib/gstid3v2mux.cc @@ -73,16 +73,18 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", GST_STATIC_CAPS ("application/x-id3")); -GST_BOILERPLATE (GstId3v2Mux, gst_id3v2_mux, GstTagLibMux, - GST_TYPE_TAG_LIB_MUX); +G_DEFINE_TYPE (GstId3v2Mux, gst_id3v2_mux, GST_TYPE_TAG_LIB_MUX); static GstBuffer *gst_id3v2_mux_render_tag (GstTagLibMux * mux, 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_TAG_LIB_MUX_CLASS (klass)->render_tag = + GST_DEBUG_FUNCPTR (gst_id3v2_mux_render_tag); gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&src_template)); @@ -97,14 +99,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 +361,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_buffer_map (buf, &map, GST_MAP_READ); 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) 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) { 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 (image) && (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; + GstMapInfo map; if (strcmp (mime_type, "text/uri-list") == 0) mime_type = "-->"; frame = new ID3v2::AttachedPictureFrame (); + gst_buffer_map (image, &map, GST_MAP_READ); + GST_DEBUG ("Attaching picture of %u bytes and mime type %s", - GST_BUFFER_SIZE (image), mime_type); + 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); + gst_buffer_unmap (image, &map); + desc = gst_structure_get_string (s, "image-description"); frame->setDescription ((desc) ? desc : ""); @@ -442,8 +448,9 @@ add_image_tag (ID3v2::Tag * id3v2tag, const GstTagList * list, } } } 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); } } } @@ -757,8 +764,7 @@ 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; } diff --git a/ext/taglib/gsttaglibmux.c b/ext/taglib/gsttaglibmux.c index 7e8cf6e250..586cb1a027 100644 --- a/ext/taglib/gsttaglibmux.c +++ b/ext/taglib/gsttaglibmux.c @@ -38,27 +38,17 @@ GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_ALWAYS, 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 gst_tag_lib_mux_change_state (GstElement * element, GstStateChange transition); -static GstFlowReturn gst_tag_lib_mux_chain (GstPad * pad, GstBuffer * buffer); -static gboolean gst_tag_lib_mux_sink_event (GstPad * pad, GstEvent * event); +static GstFlowReturn gst_tag_lib_mux_chain (GstPad * pad, GstObject * parent, + GstBuffer * buffer); +static gboolean gst_tag_lib_mux_sink_event (GstPad * pad, GstObject * parent, + GstEvent * event); static void 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); } -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 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; gstelement_class->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 -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); GstPadTemplate *tmpl; @@ -141,6 +126,7 @@ gst_tag_lib_mux_render_tag (GstTagLibMux * mux) const GstTagList *tagsetter_tags; GstTagList *taglist; GstEvent *event; + GstSegment segment; tagsetter = GST_TAG_SETTER (mux); @@ -165,13 +151,13 @@ gst_tag_lib_mux_render_tag (GstTagLibMux * mux) if (buffer == NULL) 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); /* Send newsegment event from byte position 0, so the tag really gets * written to the start of the file, independent of the upstream segment */ - gst_pad_push_event (mux->srcpad, - gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, 0, -1, 0)); + gst_segment_init (&segment, GST_FORMAT_BYTES); + gst_pad_push_event (mux->srcpad, gst_event_new_segment (&segment)); /* 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 */ @@ -201,36 +187,37 @@ static GstEvent * gst_tag_lib_mux_adjust_event_offsets (GstTagLibMux * mux, const GstEvent * newsegment_event) { - GstFormat format; gint64 start, stop, cur; + GstSegment segment; - gst_event_parse_new_segment ((GstEvent *) newsegment_event, NULL, NULL, - &format, &start, &stop, &cur); + gst_event_copy_segment ((GstEvent *) newsegment_event, &segment); - g_assert (format == GST_FORMAT_BYTES); + g_assert (segment.format == GST_FORMAT_BYTES); - if (start != -1) + if (segment.start != -1) start += mux->tag_size; - if (stop != -1) + if (segment.stop != -1) stop += mux->tag_size; - if (cur != -1) + if (segment.time != -1) cur += mux->tag_size; GST_DEBUG_OBJECT (mux, "adjusting newsegment event offsets to start=%" - G_GINT64_FORMAT ", stop=%" G_GINT64_FORMAT ", cur=%" G_GINT64_FORMAT - " (delta = +%" G_GSIZE_FORMAT ")", start, stop, cur, mux->tag_size); + G_GUINT64_FORMAT ", stop=%" G_GUINT64_FORMAT ", cur=%" G_GUINT64_FORMAT + " (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 -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) { GstFlowReturn ret; GstBuffer *tag_buffer; + GstCaps *tcaps; GST_INFO_OBJECT (mux, "Adding tags to stream"); 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; + + /* 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) { - GST_LOG_OBJECT (mux, "Adjusting buffer offset from %" G_GINT64_FORMAT - " to %" G_GINT64_FORMAT, GST_BUFFER_OFFSET (buffer), + GST_LOG_OBJECT (mux, "Adjusting buffer offset from %" G_GUINT64_FORMAT + " to %" G_GUINT64_FORMAT, GST_BUFFER_OFFSET (buffer), 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); /* ERRORS */ @@ -278,12 +269,12 @@ no_tag_buffer: } 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; gboolean result; - mux = GST_TAG_LIB_MUX (gst_pad_get_parent (pad)); + mux = GST_TAG_LIB_MUX (parent); result = FALSE; switch (GST_EVENT_TYPE (event)) { @@ -308,14 +299,14 @@ gst_tag_lib_mux_sink_event (GstPad * pad, GstEvent * event) result = TRUE; break; } - case GST_EVENT_NEWSEGMENT:{ - GstFormat fmt; + case GST_EVENT_SEGMENT:{ + 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_format_get_name (fmt)); + gst_format_get_name (segment->format)); gst_event_unref (event); break; } @@ -344,12 +335,10 @@ gst_tag_lib_mux_sink_event (GstPad * pad, GstEvent * event) break; } default: - result = gst_pad_event_default (pad, event); + result = gst_pad_event_default (pad, parent, event); break; } - gst_object_unref (mux); - return result; } diff --git a/ext/taglib/gsttaglibmux.h b/ext/taglib/gsttaglibmux.h index d26ff30867..7b7985fe99 100644 --- a/ext/taglib/gsttaglibmux.h +++ b/ext/taglib/gsttaglibmux.h @@ -60,6 +60,8 @@ struct _GstTagLibMuxClass { (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TAG_LIB_MUX)) #define GST_IS_TAG_LIB_MUX_CLASS(klass) \ (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. */ GType gst_tag_lib_mux_get_type (void);