From: Wim Taymans Date: Wed, 17 Aug 2011 08:57:52 +0000 (+0200) Subject: tagdemux: port to 0.11 X-Git-Tag: 1.19.3~511^2~7356 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d3b93e839a5d0364275adfad3e32948c89547604;p=platform%2Fupstream%2Fgstreamer.git tagdemux: port to 0.11 --- diff --git a/gst-libs/gst/tag/gsttagmux.c b/gst-libs/gst/tag/gsttagmux.c index 9c0d234..6d0a741 100644 --- a/gst-libs/gst/tag/gsttagmux.c +++ b/gst-libs/gst/tag/gsttagmux.c @@ -82,21 +82,9 @@ struct _GstTagMuxPrivate GST_DEBUG_CATEGORY_STATIC (gst_tag_mux_debug); #define GST_CAT_DEFAULT gst_tag_mux_debug -static void -gst_tag_mux_iface_init (GType tag_type) -{ - static const GInterfaceInfo tag_setter_info = { - NULL, - NULL, - NULL - }; - - g_type_add_interface_static (tag_type, GST_TYPE_TAG_SETTER, &tag_setter_info); -} - -GST_BOILERPLATE_FULL (GstTagMux, gst_tag_mux, - GstElement, GST_TYPE_ELEMENT, gst_tag_mux_iface_init); - +#define gst_tag_mux_parent_class parent_class +G_DEFINE_TYPE_WITH_CODE (GstTagMux, gst_tag_mux, GST_TYPE_ELEMENT, + G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL)); static GstStateChangeReturn gst_tag_mux_change_state (GstElement * element, GstStateChange transition); @@ -127,13 +115,6 @@ gst_tag_mux_finalize (GObject * obj) } static void -gst_tag_mux_base_init (gpointer g_class) -{ - GST_DEBUG_CATEGORY_INIT (gst_tag_mux_debug, "tagmux", 0, - "tag muxer base class"); -} - -static void gst_tag_mux_class_init (GstTagMuxClass * klass) { GObjectClass *gobject_class; @@ -146,12 +127,15 @@ gst_tag_mux_class_init (GstTagMuxClass * klass) gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_tag_mux_change_state); g_type_class_add_private (klass, sizeof (GstTagMuxPrivate)); + + GST_DEBUG_CATEGORY_INIT (gst_tag_mux_debug, "tagmux", 0, + "tag muxer base class"); } static void -gst_tag_mux_init (GstTagMux * mux, GstTagMuxClass * mux_class) +gst_tag_mux_init (GstTagMux * mux) { - GstElementClass *element_klass = GST_ELEMENT_CLASS (mux_class); + GstElementClass *element_klass = GST_ELEMENT_GET_CLASS (mux); GstPadTemplate *tmpl; mux->priv = @@ -163,7 +147,7 @@ gst_tag_mux_init (GstTagMux * mux, GstTagMuxClass * mux_class) mux->priv->sinkpad = gst_pad_new_from_template (tmpl, "sink"); } else { g_warning ("GstTagMux subclass '%s' did not install a %s pad template!\n", - G_OBJECT_CLASS_NAME (mux_class), "sink"); + G_OBJECT_CLASS_NAME (element_klass), "sink"); mux->priv->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); } gst_pad_set_chain_function (mux->priv->sinkpad, @@ -184,7 +168,7 @@ gst_tag_mux_init (GstTagMux * mux, GstTagMuxClass * mux_class) } } else { g_warning ("GstTagMux subclass '%s' did not install a %s pad template!\n", - G_OBJECT_CLASS_NAME (mux_class), "source"); + G_OBJECT_CLASS_NAME (element_klass), "source"); mux->priv->srcpad = gst_pad_new ("src", GST_PAD_SRC); } gst_element_add_pad (GST_ELEMENT (mux), mux->priv->srcpad); @@ -226,6 +210,7 @@ gst_tag_mux_render_start_tag (GstTagMux * mux) GstTagList *taglist; GstEvent *event; GstFlowReturn ret; + GstSegment segment; taglist = gst_tag_mux_get_tags (mux); @@ -243,19 +228,14 @@ gst_tag_mux_render_start_tag (GstTagMux * mux) return GST_FLOW_OK; } - if (GST_BUFFER_CAPS (buffer) == NULL) { - buffer = gst_buffer_make_metadata_writable (buffer); - gst_buffer_set_caps (buffer, GST_PAD_CAPS (mux->priv->srcpad)); - } - - mux->priv->start_tag_size = GST_BUFFER_SIZE (buffer); + mux->priv->start_tag_size = gst_buffer_get_size (buffer); GST_LOG_OBJECT (mux, "tag size = %" G_GSIZE_FORMAT " bytes", mux->priv->start_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->priv->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->priv->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 use a copy */ @@ -286,6 +266,7 @@ gst_tag_mux_render_end_tag (GstTagMux * mux) GstBuffer *buffer; GstTagList *taglist; GstFlowReturn ret; + GstSegment segment; taglist = gst_tag_mux_get_tags (mux); @@ -302,20 +283,15 @@ gst_tag_mux_render_end_tag (GstTagMux * mux) return GST_FLOW_OK; } - if (GST_BUFFER_CAPS (buffer) == NULL) { - buffer = gst_buffer_make_metadata_writable (buffer); - gst_buffer_set_caps (buffer, GST_PAD_CAPS (mux->priv->srcpad)); - } - - mux->priv->end_tag_size = GST_BUFFER_SIZE (buffer); + mux->priv->end_tag_size = gst_buffer_get_size (buffer); GST_LOG_OBJECT (mux, "tag size = %" G_GSIZE_FORMAT " bytes", mux->priv->end_tag_size); /* Send newsegment event from the end of the file, so it gets written there, independent of whatever new segment events upstream has sent us */ - gst_pad_push_event (mux->priv->srcpad, - gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, - mux->priv->max_offset, -1, 0)); + gst_segment_init (&segment, GST_FORMAT_BYTES); + segment.start = mux->priv->max_offset; + gst_pad_push_event (mux->priv->srcpad, gst_event_new_segment (&segment)); GST_BUFFER_OFFSET (buffer) = mux->priv->max_offset; ret = gst_pad_push (mux->priv->srcpad, buffer); @@ -334,27 +310,25 @@ static GstEvent * gst_tag_mux_adjust_event_offsets (GstTagMux * 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) - start += mux->priv->start_tag_size; - if (stop != -1) - stop += mux->priv->start_tag_size; - if (cur != -1) - cur += mux->priv->start_tag_size; + if (segment.start != -1) + segment.start += mux->priv->start_tag_size; + if (segment.stop != -1) + segment.stop += mux->priv->start_tag_size; + if (segment.time != -1) + segment.time += mux->priv->start_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->priv->start_tag_size); + " (delta = +%" G_GSIZE_FORMAT ")", segment.start, segment.stop, + segment.time, mux->priv->start_tag_size); - return gst_event_new_new_segment (TRUE, 1.0, format, start, stop, cur); + return gst_event_new_segment (&segment); } static GstFlowReturn @@ -376,19 +350,18 @@ gst_tag_mux_chain (GstPad * pad, GstBuffer * buffer) /* Now send the cached newsegment event that we got from upstream */ if (mux->priv->newsegment_ev) { - gint64 start; GstEvent *newseg; + GstSegment segment; GST_DEBUG_OBJECT (mux, "sending cached newsegment event"); newseg = gst_tag_mux_adjust_event_offsets (mux, mux->priv->newsegment_ev); gst_event_unref (mux->priv->newsegment_ev); mux->priv->newsegment_ev = NULL; - gst_event_parse_new_segment (newseg, NULL, NULL, NULL, &start, NULL, - NULL); + gst_event_copy_segment (newseg, &segment); gst_pad_push_event (mux->priv->srcpad, newseg); - mux->priv->current_offset = start; + mux->priv->current_offset = segment.start; mux->priv->max_offset = MAX (mux->priv->max_offset, mux->priv->current_offset); } else { @@ -398,7 +371,7 @@ gst_tag_mux_chain (GstPad * pad, GstBuffer * buffer) mux->priv->render_start_tag = FALSE; } - 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 @@ -407,9 +380,8 @@ gst_tag_mux_chain (GstPad * pad, GstBuffer * buffer) GST_BUFFER_OFFSET (buffer) += mux->priv->start_tag_size; } - length = GST_BUFFER_SIZE (buffer); + length = gst_buffer_get_size (buffer); - gst_buffer_set_caps (buffer, GST_PAD_CAPS (mux->priv->srcpad)); ret = gst_pad_push (mux->priv->srcpad, buffer); mux->priv->current_offset += length; @@ -451,15 +423,15 @@ gst_tag_mux_sink_event (GstPad * pad, GstEvent * event) result = TRUE; break; } - case GST_EVENT_NEWSEGMENT:{ - GstFormat fmt; - gint64 start; + case GST_EVENT_SEGMENT: + { + GstSegment segment; - gst_event_parse_new_segment (event, NULL, NULL, &fmt, &start, NULL, NULL); + gst_event_copy_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; } @@ -483,7 +455,7 @@ gst_tag_mux_sink_event (GstPad * pad, GstEvent * event) gst_tag_mux_adjust_event_offsets (mux, event)); gst_event_unref (event); - mux->priv->current_offset = start; + mux->priv->current_offset = segment.start; mux->priv->max_offset = MAX (mux->priv->max_offset, mux->priv->current_offset); } diff --git a/gst-libs/gst/tag/id3v2.c b/gst-libs/gst/tag/id3v2.c index 6dabddd..f1f2e4a 100644 --- a/gst-libs/gst/tag/id3v2.c +++ b/gst-libs/gst/tag/id3v2.c @@ -96,37 +96,57 @@ guint gst_tag_get_id3v2_tag_size (GstBuffer * buffer) { guint8 *data, flags; - guint size; + gsize size; + guint result = 0; g_return_val_if_fail (buffer != NULL, 0); - if (GST_BUFFER_SIZE (buffer) < ID3V2_HDR_SIZE) - return 0; + data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ); - data = GST_BUFFER_DATA (buffer); + if (size < ID3V2_HDR_SIZE) + goto too_small; /* Check for 'ID3' string at start of buffer */ - if (data[0] != 'I' || data[1] != 'D' || data[2] != '3') { - GST_DEBUG ("No ID3v2 tag in data"); - return 0; - } + if (data[0] != 'I' || data[1] != 'D' || data[2] != '3') + goto no_tag; /* Read the flags */ flags = data[5]; /* Read the size from the header */ - size = id3v2_read_synch_uint (data + 6, 4); - if (size == 0) - return ID3V2_HDR_SIZE; + result = id3v2_read_synch_uint (data + 6, 4); + if (result == 0) + goto empty; - size += ID3V2_HDR_SIZE; + result += ID3V2_HDR_SIZE; /* Expand the read size to include a footer if there is one */ if ((flags & ID3V2_HDR_FLAG_FOOTER)) - size += 10; + result += 10; - GST_DEBUG ("ID3v2 tag, size: %u bytes", size); - return size; + GST_DEBUG ("ID3v2 tag, size: %u bytes", result); + +done: + gst_buffer_unmap (buffer, data, size); + + return result; + +too_small: + { + GST_DEBUG ("size too small"); + goto done; + } +no_tag: + { + GST_DEBUG ("No ID3v2 tag in data"); + goto done; + } +empty: + { + GST_DEBUG ("Empty tag size"); + result = ID3V2_HDR_SIZE; + goto done; + } } guint8 * @@ -174,6 +194,7 @@ gst_tag_list_from_id3v2_tag (GstBuffer * buffer) { guint8 *data, *uu_data = NULL; guint read_size; + gsize size; ID3TagsWorking work; guint8 flags; guint16 version; @@ -184,7 +205,7 @@ gst_tag_list_from_id3v2_tag (GstBuffer * buffer) if (read_size < ID3V2_HDR_SIZE) return NULL; - data = GST_BUFFER_DATA (buffer); + data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ); /* Read the version */ version = GST_READ_UINT16_BE (data + 3); @@ -193,12 +214,8 @@ gst_tag_list_from_id3v2_tag (GstBuffer * buffer) flags = data[5]; /* Validate the version. At the moment, we only support up to 2.4.0 */ - if (ID3V2_VER_MAJOR (version) > 4 || ID3V2_VER_MINOR (version) > 0) { - GST_WARNING ("ID3v2 tag is from revision 2.%d.%d, " - "but decoder only supports 2.%d.%d. Ignoring as per spec.", - version >> 8, version & 0xff, ID3V2_VERSION >> 8, ID3V2_VERSION & 0xff); - return NULL; - } + if (ID3V2_VER_MAJOR (version) > 4 || ID3V2_VER_MINOR (version) > 0) + goto wrong_version; GST_DEBUG ("ID3v2 header flags: %s %s %s %s", (flags & ID3V2_HDR_FLAG_UNSYNC) ? "UNSYNC" : "", @@ -207,25 +224,20 @@ gst_tag_list_from_id3v2_tag (GstBuffer * buffer) (flags & ID3V2_HDR_FLAG_FOOTER) ? "FOOTER" : ""); /* This shouldn't really happen! Caller should have checked first */ - if (GST_BUFFER_SIZE (buffer) < read_size) { - GST_DEBUG - ("Found ID3v2 tag with revision 2.%d.%d - need %u more bytes to read", - version >> 8, version & 0xff, - (guint) (read_size - GST_BUFFER_SIZE (buffer))); - return NULL; - } + if (size < read_size) + goto not_enough_data; GST_DEBUG ("Reading ID3v2 tag with revision 2.%d.%d of size %u", version >> 8, version & 0xff, read_size); - GST_MEMDUMP ("ID3v2 tag", GST_BUFFER_DATA (buffer), read_size); + GST_MEMDUMP ("ID3v2 tag", data, read_size); memset (&work, 0, sizeof (ID3TagsWorking)); work.buffer = buffer; work.hdr.version = version; work.hdr.size = read_size; work.hdr.flags = flags; - work.hdr.frame_data = GST_BUFFER_DATA (buffer) + ID3V2_HDR_SIZE; + work.hdr.frame_data = data + ID3V2_HDR_SIZE; if (flags & ID3V2_HDR_FLAG_FOOTER) work.hdr.frame_data_size = read_size - ID3V2_HDR_SIZE - 10; else @@ -246,7 +258,27 @@ gst_tag_list_from_id3v2_tag (GstBuffer * buffer) g_free (uu_data); + gst_buffer_unmap (buffer, data, size); + return work.tags; + + /* ERRORS */ +wrong_version: + { + GST_WARNING ("ID3v2 tag is from revision 2.%d.%d, " + "but decoder only supports 2.%d.%d. Ignoring as per spec.", + version >> 8, version & 0xff, ID3V2_VERSION >> 8, ID3V2_VERSION & 0xff); + gst_buffer_unmap (buffer, data, size); + return NULL; + } +not_enough_data: + { + GST_DEBUG + ("Found ID3v2 tag with revision 2.%d.%d - need %u more bytes to read", + version >> 8, version & 0xff, (guint) (read_size - size)); + gst_buffer_unmap (buffer, data, size); + return NULL; + } } static guint @@ -365,9 +397,11 @@ static void id3v2_add_id3v2_frame_blob_to_taglist (ID3TagsWorking * work, guint size) { GstBuffer *blob; - GstCaps *caps; guint8 *frame_data; +#if 0 + GstCaps *caps; gchar *media_type; +#endif guint frame_size, header_size; guint i; @@ -388,7 +422,7 @@ id3v2_add_id3v2_frame_blob_to_taglist (ID3TagsWorking * work, guint size) frame_size = size + header_size; blob = gst_buffer_new_and_alloc (frame_size); - memcpy (GST_BUFFER_DATA (blob), frame_data, frame_size); + gst_buffer_fill (blob, 0, frame_data, frame_size); /* Sanitize frame id */ for (i = 0; i < 4; i++) { @@ -396,6 +430,7 @@ id3v2_add_id3v2_frame_blob_to_taglist (ID3TagsWorking * work, guint size) frame_data[i] = '_'; } +#if 0 media_type = g_strdup_printf ("application/x-gst-id3v2-%c%c%c%c-frame", g_ascii_tolower (frame_data[0]), g_ascii_tolower (frame_data[1]), g_ascii_tolower (frame_data[2]), g_ascii_tolower (frame_data[3])); @@ -404,6 +439,7 @@ id3v2_add_id3v2_frame_blob_to_taglist (ID3TagsWorking * work, guint size) gst_buffer_set_caps (blob, caps); gst_caps_unref (caps); g_free (media_type); +#endif /* gst_util_dump_mem (GST_BUFFER_DATA (blob), GST_BUFFER_SIZE (blob)); */ @@ -416,7 +452,6 @@ static gboolean id3v2_frames_to_tag_list (ID3TagsWorking * work, guint size) { guint frame_hdr_size; - guint8 *start; /* Extended header if present */ if (work->hdr.flags & ID3V2_HDR_FLAG_EXTHDR) { @@ -438,7 +473,6 @@ id3v2_frames_to_tag_list (ID3TagsWorking * work, guint size) work->hdr.frame_data_size -= work->hdr.ext_hdr_size; } - start = GST_BUFFER_DATA (work->buffer); frame_hdr_size = id3v2_frame_hdr_size (work->hdr.version); if (work->hdr.frame_data_size <= frame_hdr_size) { GST_DEBUG ("Tag has no data frames. Broken tag"); @@ -520,6 +554,7 @@ id3v2_frames_to_tag_list (ID3TagsWorking * work, guint size) } } #if 1 +#if 0 GST_LOG ("Frame @ %ld (0x%02lx) id %s size %u, next=%ld (0x%02lx) obsolete=%d", (glong) (work->hdr.frame_data - start), @@ -527,6 +562,7 @@ id3v2_frames_to_tag_list (ID3TagsWorking * work, guint size) (glong) (work->hdr.frame_data + frame_hdr_size + frame_size - start), (glong) (work->hdr.frame_data + frame_hdr_size + frame_size - start), obsolete_id); +#endif #define flag_string(flag,str) \ ((frame_flags & (flag)) ? (str) : "") GST_LOG ("Frame header flags: 0x%04x %s %s %s %s %s %s %s", frame_flags,