From 41025681bc6d86a01aa5d58316ae9c5d87eecd4f Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 25 Mar 2011 19:52:30 +0100 Subject: [PATCH] tags: port to new metadata and memory API --- gst-libs/gst/netbuffer/gstnetbuffer.c | 19 ++-- gst-libs/gst/tag/gstexiftag.c | 178 +++++++++++++++++++++++----------- gst-libs/gst/tag/gsttagdemux.c | 100 ++++++++++++------- gst-libs/gst/tag/gstvorbistag.c | 26 ++--- gst-libs/gst/tag/gstxmptag.c | 50 +++++----- gst-libs/gst/tag/tag.h | 9 +- gst-libs/gst/tag/tags.c | 26 +++-- 7 files changed, 253 insertions(+), 155 deletions(-) diff --git a/gst-libs/gst/netbuffer/gstnetbuffer.c b/gst-libs/gst/netbuffer/gstnetbuffer.c index 5c62553..78c6643 100644 --- a/gst-libs/gst/netbuffer/gstnetbuffer.c +++ b/gst-libs/gst/netbuffer/gstnetbuffer.c @@ -35,21 +35,13 @@ #include "gstnetbuffer.h" static void -meta_net_address_transform (GstBuffer * transbuf, GstMetaNetAddress * meta, - GstBuffer * buffer, GstMetaTransformData * data) +meta_net_address_copy (GstBuffer * copybuf, GstMetaNetAddress * meta, + GstBuffer * buffer, gsize offset, gsize size) { GstMetaNetAddress *naddr; - switch (data->type) { - case GST_META_TRANSFORM_TRIM: - case GST_META_TRANSFORM_MAKE_WRITABLE: - case GST_META_TRANSFORM_COPY: - default: - /* always copy */ - naddr = gst_buffer_add_meta_net_address (transbuf); - memcpy (&naddr->naddr, &meta->naddr, sizeof (meta->naddr)); - break; - } + naddr = gst_buffer_add_meta_net_address (copybuf); + memcpy (&naddr->naddr, &meta->naddr, sizeof (meta->naddr)); } const GstMetaInfo * @@ -62,7 +54,8 @@ gst_meta_net_address_get_info (void) sizeof (GstMetaNetAddress), (GstMetaInitFunction) NULL, (GstMetaFreeFunction) NULL, - (GstMetaTransformFunction) meta_net_address_transform, + (GstMetaCopyFunction) meta_net_address_copy, + (GstMetaTransformFunction) NULL, (GstMetaSerializeFunction) NULL, (GstMetaDeserializeFunction) NULL); } return meta_info; diff --git a/gst-libs/gst/tag/gstexiftag.c b/gst-libs/gst/tag/gstexiftag.c index cc39acd..badf2fc 100644 --- a/gst-libs/gst/tag/gstexiftag.c +++ b/gst-libs/gst/tag/gstexiftag.c @@ -231,7 +231,7 @@ struct _GstExifWriter struct _GstExifReader { GstTagList *taglist; - const GstBuffer *buffer; + GstBuffer *buffer; guint32 base_offset; gint byte_order; @@ -451,7 +451,7 @@ static const GstExifTagMatch tag_map_gps[] = { /* GstExifReader functions */ static void gst_exif_reader_init (GstExifReader * reader, gint byte_order, - const GstBuffer * buf, guint32 base_offset) + GstBuffer * buf, guint32 base_offset) { reader->taglist = gst_tag_list_new (); reader->buffer = buf; @@ -849,9 +849,10 @@ write_exif_undefined_tag_from_taglist (GstExifWriter * writer, const GstTagList * taglist, const GstExifTagMatch * exiftag) { const GValue *value; - const guint8 *data = NULL; - gint size = 0; + guint8 *data = NULL; + gsize size = 0; gint tag_size = gst_tag_list_get_tag_size (taglist, exiftag->gst_tag); + GstBuffer *buf = NULL; if (tag_size != 1) { GST_WARNING ("Only the first item in the taglist will be serialized"); @@ -868,10 +869,8 @@ write_exif_undefined_tag_from_taglist (GstExifWriter * writer, break; default: if (G_VALUE_TYPE (value) == GST_TYPE_BUFFER) { - GstBuffer *buf = gst_value_get_buffer (value); - - data = GST_BUFFER_DATA (buf); - size = GST_BUFFER_SIZE (buf); + buf = gst_value_get_buffer (value); + data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ); } else { GST_WARNING ("Conversion from %s to raw data not supported", G_VALUE_TYPE_NAME (value)); @@ -879,10 +878,11 @@ write_exif_undefined_tag_from_taglist (GstExifWriter * writer, break; } - if (size == 0) - return; + if (size > 0) + write_exif_undefined_tag (writer, exiftag->exif_tag, data, size); - write_exif_undefined_tag (writer, exiftag->exif_tag, data, size); + if (buf) + gst_buffer_unmap (buf, data, size); } static void @@ -1122,6 +1122,9 @@ parse_exif_ascii_tag (GstExifReader * reader, const GstExifTagMatch * tag, guint32 real_offset; if (count > 4) { + guint8 *data; + gsize size; + if (offset < reader->base_offset) { GST_WARNING ("Offset is smaller (%u) than base offset (%u)", offset, reader->base_offset); @@ -1129,15 +1132,17 @@ parse_exif_ascii_tag (GstExifReader * reader, const GstExifTagMatch * tag, } real_offset = offset - reader->base_offset; - if (real_offset >= GST_BUFFER_SIZE (reader->buffer)) { + + data = gst_buffer_map (reader->buffer, &size, NULL, GST_MAP_READ); + if (real_offset >= size) { GST_WARNING ("Invalid offset %u for buffer of size %u, not adding tag %s", - real_offset, GST_BUFFER_SIZE (reader->buffer), tag->gst_tag); + real_offset, size, tag->gst_tag); + gst_buffer_unmap (reader->buffer, data, size); return; } - str = - g_strndup ((gchar *) (GST_BUFFER_DATA (reader->buffer) + real_offset), - count); + str = g_strndup ((gchar *) (data + real_offset), count); + gst_buffer_unmap (reader->buffer, data, size); } else { str = g_strndup ((gchar *) offset_as_data, count); } @@ -1198,6 +1203,9 @@ parse_exif_undefined_tag (GstExifReader * reader, const GstExifTagMatch * tag, guint32 real_offset; if (count > 4) { + guint8 *bdata; + gsize bsize; + if (offset < reader->base_offset) { GST_WARNING ("Offset is smaller (%u) than base offset (%u)", offset, reader->base_offset); @@ -1205,16 +1213,22 @@ parse_exif_undefined_tag (GstExifReader * reader, const GstExifTagMatch * tag, } real_offset = offset - reader->base_offset; - if (real_offset >= GST_BUFFER_SIZE (reader->buffer)) { + + bdata = gst_buffer_map (reader->buffer, &bsize, NULL, GST_MAP_READ); + + if (real_offset >= bsize) { GST_WARNING ("Invalid offset %u for buffer of size %u, not adding tag %s", - real_offset, GST_BUFFER_SIZE (reader->buffer), tag->gst_tag); + real_offset, bsize, tag->gst_tag); + gst_buffer_unmap (reader->buffer, bdata, bsize); return; } /* +1 because it could be a string without the \0 */ data = malloc (sizeof (guint8) * count + 1); - memcpy (data, GST_BUFFER_DATA (reader->buffer) + real_offset, count); + memcpy (data, bdata + real_offset, count); data[count] = 0; + + gst_buffer_unmap (reader->buffer, bdata, bsize); } else { data = malloc (sizeof (guint8) * count + 1); memcpy (data, (guint8 *) offset_as_data, count); @@ -1226,9 +1240,8 @@ parse_exif_undefined_tag (GstExifReader * reader, const GstExifTagMatch * tag, GstBuffer *buf; buf = gst_buffer_new (); - GST_BUFFER_DATA (buf) = data; - GST_BUFFER_MALLOCDATA (buf) = data; - GST_BUFFER_SIZE (buf) = count; + gst_buffer_take_memory (buf, + gst_memory_new_wrapped (0, data, g_free, count, 0, count)); data = NULL; gst_tag_list_add (reader->taglist, GST_TAG_MERGE_APPEND, tag->gst_tag, @@ -1254,6 +1267,8 @@ exif_reader_read_rational_tag (GstExifReader * exif_reader, guint32 real_offset; gint32 frac_n = 0; gint32 frac_d = 0; + guint8 *data; + gsize size; if (count > 1) { GST_WARNING ("Rationals with multiple entries are not supported"); @@ -1265,13 +1280,15 @@ exif_reader_read_rational_tag (GstExifReader * exif_reader, } real_offset = offset - exif_reader->base_offset; - if (real_offset >= GST_BUFFER_SIZE (exif_reader->buffer)) { - GST_WARNING ("Invalid offset %u for buffer of size %u", - real_offset, GST_BUFFER_SIZE (exif_reader->buffer)); - return FALSE; + + data = gst_buffer_map (exif_reader->buffer, &size, NULL, GST_MAP_READ); + + if (real_offset >= size) { + GST_WARNING ("Invalid offset %u for buffer of size %u", real_offset, size); + goto reader_fail; } - gst_byte_reader_init_from_buffer (&data_reader, exif_reader->buffer); + gst_byte_reader_init (&data_reader, data, size); if (!gst_byte_reader_set_pos (&data_reader, real_offset)) goto reader_fail; @@ -1305,10 +1322,13 @@ exif_reader_read_rational_tag (GstExifReader * exif_reader, if (_frac_d) *_frac_d = frac_d; + gst_buffer_unmap (exif_reader->buffer, data, size); + return TRUE; reader_fail: GST_WARNING ("Failed to read from byte reader. (Buffer too short?)"); + gst_buffer_unmap (exif_reader->buffer, data, size); return FALSE; } @@ -1408,12 +1428,17 @@ write_exif_ifd (const GstTagList * taglist, gboolean byte_order, } if (inner_ifd) { + guint8 *data; + gsize size; + GST_DEBUG ("Adding inner ifd: %x", tag_map[i].exif_tag); gst_exif_writer_write_tag_header (&writer, tag_map[i].exif_tag, EXIF_TYPE_LONG, 1, gst_byte_writer_get_size (&writer.datawriter), FALSE); - gst_byte_writer_put_data (&writer.datawriter, - GST_BUFFER_DATA (inner_ifd), GST_BUFFER_SIZE (inner_ifd)); + + data = gst_buffer_map (inner_ifd, &size, NULL, GST_MAP_READ); + gst_byte_writer_put_data (&writer.datawriter, data, size); + gst_buffer_unmap (inner_ifd, data, size); gst_buffer_unref (inner_ifd); } continue; @@ -1483,15 +1508,17 @@ parse_exif_ifd (GstExifReader * exif_reader, gint buf_offset, GstByteReader reader; guint16 entries = 0; guint16 i; + guint8 *data; + gsize size; g_return_val_if_fail (exif_reader->byte_order == G_LITTLE_ENDIAN || exif_reader->byte_order == G_BIG_ENDIAN, FALSE); - gst_byte_reader_init_from_buffer (&reader, exif_reader->buffer); - if (!gst_byte_reader_set_pos (&reader, buf_offset)) { - GST_WARNING ("Buffer offset invalid when parsing exif ifd"); - return FALSE; - } + data = gst_buffer_map (exif_reader->buffer, &size, NULL, GST_MAP_READ); + + gst_byte_reader_init (&reader, data, size); + if (!gst_byte_reader_set_pos (&reader, buf_offset)) + goto invalid_offset; /* read the IFD entries number */ if (exif_reader->byte_order == G_LITTLE_ENDIAN) { @@ -1597,12 +1624,20 @@ parse_exif_ifd (GstExifReader * exif_reader, gint buf_offset, } } } + gst_buffer_unmap (exif_reader->buffer, data, size); return TRUE; +invalid_offset: + { + GST_WARNING ("Buffer offset invalid when parsing exif ifd"); + gst_buffer_unmap (exif_reader->buffer, data, size); + return FALSE; + } read_error: { GST_WARNING ("Failed to parse the exif ifd"); + gst_buffer_unmap (exif_reader->buffer, data, size); return FALSE; } } @@ -1643,14 +1678,18 @@ gst_tag_list_to_exif_buffer_with_tiff_header (const GstTagList * taglist) { GstBuffer *ifd; GstByteWriter writer; - guint size; + gsize size; + guint8 *data; ifd = gst_tag_list_to_exif_buffer (taglist, G_BYTE_ORDER, 8); if (ifd == NULL) { GST_WARNING ("Failed to create exif buffer"); return NULL; } - size = TIFF_HEADER_SIZE + GST_BUFFER_SIZE (ifd); + + data = gst_buffer_map (ifd, &size, NULL, GST_MAP_READ); + + size += TIFF_HEADER_SIZE; /* TODO what is the correct endianness here? */ gst_byte_writer_init_with_size (&writer, size, FALSE); @@ -1664,17 +1703,19 @@ gst_tag_list_to_exif_buffer_with_tiff_header (const GstTagList * taglist) gst_byte_writer_put_uint16_be (&writer, 42); gst_byte_writer_put_uint32_be (&writer, 8); } - if (!gst_byte_writer_put_data (&writer, GST_BUFFER_DATA (ifd), - GST_BUFFER_SIZE (ifd))) { + if (!gst_byte_writer_put_data (&writer, data, size)) { GST_WARNING ("Byte writer size mismatch"); /* reaching here is a programming error because we should have a buffer * large enough */ g_assert_not_reached (); + gst_buffer_unmap (ifd, data, size); gst_buffer_unref (ifd); gst_byte_writer_reset (&writer); return NULL; } + gst_buffer_unmap (ifd, data, size); gst_buffer_unref (ifd); + return gst_byte_writer_reset_and_get_buffer (&writer); } @@ -1694,7 +1735,7 @@ gst_tag_list_to_exif_buffer_with_tiff_header (const GstTagList * taglist) * Since: 0.10.30 */ GstTagList * -gst_tag_list_from_exif_buffer (const GstBuffer * buffer, gint byte_order, +gst_tag_list_from_exif_buffer (GstBuffer * buffer, gint byte_order, guint32 base_offset) { GstExifReader reader; @@ -1727,7 +1768,7 @@ read_error: * Since: 0.10.30 */ GstTagList * -gst_tag_list_from_exif_buffer_with_tiff_header (const GstBuffer * buffer) +gst_tag_list_from_exif_buffer_with_tiff_header (GstBuffer * buffer) { GstByteReader reader; guint16 fortytwo = 42; @@ -1735,11 +1776,14 @@ gst_tag_list_from_exif_buffer_with_tiff_header (const GstBuffer * buffer) guint32 offset; GstTagList *taglist = NULL; GstBuffer *subbuffer; + guint8 *data, *sdata; + gsize size, ssize; + + data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ); - GST_LOG ("Parsing exif tags with tiff header of size %u", - GST_BUFFER_SIZE (buffer)); + GST_LOG ("Parsing exif tags with tiff header of size %u", size); - gst_byte_reader_init_from_buffer (&reader, buffer); + gst_byte_reader_init (&reader, data, size); GST_LOG ("Parsing the tiff header"); if (!gst_byte_reader_get_uint16_be (&reader, &endianness)) { @@ -1754,32 +1798,42 @@ gst_tag_list_from_exif_buffer_with_tiff_header (const GstBuffer * buffer) if (!gst_byte_reader_get_uint16_be (&reader, &fortytwo) || !gst_byte_reader_get_uint32_be (&reader, &offset)) goto byte_reader_fail; - } else { - GST_WARNING ("Invalid endianness number %u", endianness); - return NULL; - } + } else + goto invalid_endianness; - if (fortytwo != 42) { - GST_WARNING ("Invalid magic number %u, should be 42", fortytwo); - return NULL; - } + if (fortytwo != 42) + goto invalid_magic; - subbuffer = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (buffer) - - (TIFF_HEADER_SIZE - 2)); - memcpy (GST_BUFFER_DATA (subbuffer), - GST_BUFFER_DATA (buffer) + TIFF_HEADER_SIZE, - GST_BUFFER_SIZE (buffer) - TIFF_HEADER_SIZE); + subbuffer = gst_buffer_new_and_alloc (size - (TIFF_HEADER_SIZE - 2)); + + sdata = gst_buffer_map (subbuffer, &ssize, NULL, GST_MAP_WRITE); + memcpy (sdata, data + TIFF_HEADER_SIZE, size - TIFF_HEADER_SIZE); + gst_buffer_unmap (subbuffer, sdata, ssize); taglist = gst_tag_list_from_exif_buffer (subbuffer, endianness == TIFF_LITTLE_ENDIAN ? G_LITTLE_ENDIAN : G_BIG_ENDIAN, 8); gst_buffer_unref (subbuffer); + +done: + gst_buffer_unmap (buffer, data, size); + return taglist; byte_reader_fail: { GST_WARNING ("Failed to read values from buffer"); - return NULL; + goto done; + } +invalid_endianness: + { + GST_WARNING ("Invalid endianness number %u", endianness); + goto done; + } +invalid_magic: + { + GST_WARNING ("Invalid magic number %u, should be 42", fortytwo); + goto done; } } @@ -1879,6 +1933,8 @@ deserialize_geo_coordinate (GstExifReader * exif_reader, gdouble degrees; gdouble minutes; gdouble seconds; + guint8 *data = NULL; + gsize size = 0; GST_LOG ("Starting to parse %s tag in exif 0x%x", exiftag->gst_tag, exiftag->exif_tag); @@ -1935,8 +1991,11 @@ deserialize_geo_coordinate (GstExifReader * exif_reader, return ret; } + data = gst_buffer_map (exif_reader->buffer, &size, NULL, GST_MAP_READ); + /* now parse the fractions */ - gst_byte_reader_init_from_buffer (&fractions_reader, exif_reader->buffer); + gst_byte_reader_init (&fractions_reader, data, size); + if (!gst_byte_reader_set_pos (&fractions_reader, next_tagdata.offset - exif_reader->base_offset)) goto reader_fail; @@ -1958,6 +2017,7 @@ deserialize_geo_coordinate (GstExifReader * exif_reader, !gst_byte_reader_get_uint32_be (&fractions_reader, &seconds_d)) goto reader_fail; } + gst_buffer_unmap (exif_reader->buffer, data, size); GST_DEBUG ("Read degrees fraction for tag %s: %u/%u %u/%u %u/%u", exiftag->gst_tag, degrees_n, degrees_d, minutes_n, minutes_d, @@ -1979,6 +2039,8 @@ deserialize_geo_coordinate (GstExifReader * exif_reader, reader_fail: GST_WARNING ("Failed to read fields from buffer (too short?)"); + if (data) + gst_buffer_unmap (exif_reader->buffer, data, size); return ret; } diff --git a/gst-libs/gst/tag/gsttagdemux.c b/gst-libs/gst/tag/gsttagdemux.c index 8bb3314..d927f8d 100644 --- a/gst-libs/gst/tag/gsttagdemux.c +++ b/gst-libs/gst/tag/gsttagdemux.c @@ -102,6 +102,7 @@ struct _GstTagDemuxPrivate GstTagDemuxState state; GstBuffer *collect; + gsize collect_size; GstCaps *src_caps; GstTagList *event_tags; @@ -254,6 +255,7 @@ gst_tag_demux_reset (GstTagDemux * tagdemux) tagdemux->priv->send_tag_event = FALSE; gst_buffer_replace (buffer_p, NULL); + tagdemux->priv->collect_size = 0; gst_caps_replace (caps_p, NULL); gst_tag_demux_remove_srcpad (tagdemux); @@ -388,18 +390,23 @@ gst_tag_demux_remove_srcpad (GstTagDemux * demux) * also return TRUE and set *buf_ref to NULL if the buffer was before * the start of the data */ static gboolean -gst_tag_demux_trim_buffer (GstTagDemux * tagdemux, GstBuffer ** buf_ref) +gst_tag_demux_trim_buffer (GstTagDemux * tagdemux, GstBuffer ** buf_ref, + gsize * buf_size) { GstBuffer *buf = *buf_ref; guint trim_start = 0; - guint out_size = GST_BUFFER_SIZE (buf); - guint64 out_offset = GST_BUFFER_OFFSET (buf); + guint out_size, bsize; + guint64 out_offset, boffset; gboolean need_sub = FALSE; + bsize = out_size = gst_buffer_get_size (buf); + boffset = out_offset = GST_BUFFER_OFFSET (buf); + /* Adjust offset and length */ if (!GST_BUFFER_OFFSET_IS_VALID (buf)) { /* Can't change anything without an offset */ + *buf_size = bsize; return TRUE; } @@ -439,21 +446,22 @@ gst_tag_demux_trim_buffer (GstTagDemux * tagdemux, GstBuffer ** buf_ref) } if (need_sub == TRUE) { - if (out_size != GST_BUFFER_SIZE (buf) || !gst_buffer_is_writable (buf)) { + if (out_size != bsize || !gst_buffer_is_writable (buf)) { GstBuffer *sub; GST_DEBUG_OBJECT (tagdemux, "Sub-buffering to trim size %d offset %" G_GINT64_FORMAT " to %d offset %" G_GINT64_FORMAT, - GST_BUFFER_SIZE (buf), GST_BUFFER_OFFSET (buf), out_size, out_offset); + bsize, boffset, out_size, out_offset); sub = gst_buffer_create_sub (buf, trim_start, out_size); g_return_val_if_fail (sub != NULL, FALSE); gst_buffer_unref (buf); *buf_ref = buf = sub; + *buf_size = out_size; } else { GST_DEBUG_OBJECT (tagdemux, "Adjusting buffer from size %d offset %" G_GINT64_FORMAT " to %d offset %" G_GINT64_FORMAT, - GST_BUFFER_SIZE (buf), GST_BUFFER_OFFSET (buf), out_size, out_offset); + bsize, boffset, out_size, out_offset); } GST_BUFFER_OFFSET (buf) = out_offset; @@ -485,7 +493,7 @@ gst_tag_demux_chain_parse_tag (GstTagDemux * demux, GstBuffer * collect) guint tagsize = 0; guint available; - g_assert (gst_buffer_is_metadata_writable (collect)); + g_assert (gst_buffer_is_writable (collect)); klass = GST_TAG_DEMUX_CLASS (G_OBJECT_GET_CLASS (demux)); @@ -501,7 +509,7 @@ gst_tag_demux_chain_parse_tag (GstTagDemux * demux, GstBuffer * collect) g_assert (klass->identify_tag != NULL); g_assert (klass->parse_tag != NULL); - available = GST_BUFFER_SIZE (collect); + available = gst_buffer_get_size (collect); if (available < klass->min_start_size) { GST_DEBUG_OBJECT (demux, "Only %u bytes available, but %u needed " @@ -535,13 +543,13 @@ gst_tag_demux_chain_parse_tag (GstTagDemux * demux, GstBuffer * collect) return; /* wait for more data */ } - saved_size = GST_BUFFER_SIZE (collect); - GST_BUFFER_SIZE (collect) = tagsize; + saved_size = gst_buffer_get_size (collect); + gst_buffer_set_size (collect, tagsize); newsize = tagsize; parse_ret = klass->parse_tag (demux, collect, TRUE, &newsize, &tags); - GST_BUFFER_SIZE (collect) = saved_size; + gst_buffer_set_size (collect, saved_size); switch (parse_ret) { case GST_TAG_DEMUX_RESULT_OK: @@ -572,14 +580,17 @@ static GstFlowReturn gst_tag_demux_chain (GstPad * pad, GstBuffer * buf) { GstTagDemux *demux; + gsize size; demux = GST_TAG_DEMUX (GST_PAD_PARENT (pad)); + size = gst_buffer_get_size (buf); + /* Update our segment last_stop info */ if (demux->priv->segment.format == GST_FORMAT_BYTES) { if (GST_BUFFER_OFFSET_IS_VALID (buf)) demux->priv->segment.last_stop = GST_BUFFER_OFFSET (buf); - demux->priv->segment.last_stop += GST_BUFFER_SIZE (buf); + demux->priv->segment.last_stop += size; } else if (demux->priv->segment.format == GST_FORMAT_TIME) { if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) demux->priv->segment.last_stop = GST_BUFFER_TIMESTAMP (buf); @@ -592,12 +603,12 @@ gst_tag_demux_chain (GstPad * pad, GstBuffer * buf) } else { demux->priv->collect = gst_buffer_join (demux->priv->collect, buf); } + demux->priv->collect_size += size; buf = NULL; switch (demux->priv->state) { case GST_TAG_DEMUX_READ_START_TAG: - demux->priv->collect = - gst_buffer_make_metadata_writable (demux->priv->collect); + demux->priv->collect = gst_buffer_make_writable (demux->priv->collect); gst_tag_demux_chain_parse_tag (demux, demux->priv->collect); if (demux->priv->state != GST_TAG_DEMUX_TYPEFINDING) break; @@ -605,19 +616,20 @@ gst_tag_demux_chain (GstPad * pad, GstBuffer * buf) case GST_TAG_DEMUX_TYPEFINDING:{ GstTypeFindProbability probability = 0; GstBuffer *typefind_buf = NULL; + gsize typefind_size; GstCaps *caps; - if (GST_BUFFER_SIZE (demux->priv->collect) < + if (demux->priv->collect_size < TYPE_FIND_MIN_SIZE + demux->priv->strip_start) break; /* Go get more data first */ GST_DEBUG_OBJECT (demux, "Typefinding with size %d", - GST_BUFFER_SIZE (demux->priv->collect)); + demux->priv->collect_size); /* Trim the buffer and adjust offset for typefinding */ typefind_buf = demux->priv->collect; gst_buffer_ref (typefind_buf); - if (!gst_tag_demux_trim_buffer (demux, &typefind_buf)) + if (!gst_tag_demux_trim_buffer (demux, &typefind_buf, &typefind_size)) return GST_FLOW_UNEXPECTED; if (typefind_buf == NULL) @@ -627,7 +639,7 @@ gst_tag_demux_chain (GstPad * pad, GstBuffer * buf) typefind_buf, &probability); if (caps == NULL) { - if (GST_BUFFER_SIZE (typefind_buf) < TYPE_FIND_MAX_SIZE) { + if (typefind_size < TYPE_FIND_MAX_SIZE) { /* Just break for more data */ gst_buffer_unref (typefind_buf); return GST_FLOW_OK; @@ -639,6 +651,7 @@ gst_tag_demux_chain (GstPad * pad, GstBuffer * buf) gst_buffer_unref (typefind_buf); gst_buffer_unref (demux->priv->collect); demux->priv->collect = NULL; + demux->priv->collect_size = 0; return GST_FLOW_ERROR; } gst_buffer_unref (typefind_buf); @@ -660,12 +673,14 @@ gst_tag_demux_chain (GstPad * pad, GstBuffer * buf) } case GST_TAG_DEMUX_STREAMING:{ GstBuffer *outbuf = NULL; + gsize outbuf_size; /* Trim the buffer and adjust offset */ if (demux->priv->collect) { outbuf = demux->priv->collect; demux->priv->collect = NULL; - if (!gst_tag_demux_trim_buffer (demux, &outbuf)) + demux->priv->collect_size = 0; + if (!gst_tag_demux_trim_buffer (demux, &outbuf, &outbuf_size)) return GST_FLOW_UNEXPECTED; } if (outbuf) { @@ -693,7 +708,7 @@ gst_tag_demux_chain (GstPad * pad, GstBuffer * buf) } /* Ensure the caps are set correctly */ - outbuf = gst_buffer_make_metadata_writable (outbuf); + outbuf = gst_buffer_make_writable (outbuf); gst_buffer_set_caps (outbuf, GST_PAD_CAPS (demux->priv->srcpad)); GST_LOG_OBJECT (demux, "Pushing buffer %p", outbuf); @@ -885,6 +900,7 @@ gst_tag_demux_pull_end_tag (GstTagDemux * demux, GstTagList ** tags) gboolean res = FALSE; guint64 offset; guint tagsize; + gsize bsize; klass = GST_TAG_DEMUX_CLASS (G_OBJECT_GET_CLASS (demux)); @@ -913,9 +929,11 @@ gst_tag_demux_pull_end_tag (GstTagDemux * demux, GstTagList ** tags) goto done; } - if (GST_BUFFER_SIZE (buffer) < klass->min_end_size) { + bsize = gst_buffer_get_size (buffer); + + if (bsize < klass->min_end_size) { GST_DEBUG_OBJECT (demux, "Only managed to read %u bytes from file " - "(required: %u bytes)", GST_BUFFER_SIZE (buffer), klass->min_end_size); + "(required: %u bytes)", bsize, klass->min_end_size); goto done; } @@ -937,7 +955,7 @@ gst_tag_demux_pull_end_tag (GstTagDemux * demux, GstTagList ** tags) g_assert (tagsize >= klass->min_end_size); /* Get buffer that's exactly the requested size */ - if (GST_BUFFER_SIZE (buffer) != tagsize) { + if (bsize != tagsize) { gst_buffer_unref (buffer); buffer = NULL; @@ -953,22 +971,24 @@ gst_tag_demux_pull_end_tag (GstTagDemux * demux, GstTagList ** tags) goto done; } - if (GST_BUFFER_SIZE (buffer) < tagsize) { + bsize = gst_buffer_get_size (buffer); + + if (bsize < tagsize) { GST_DEBUG_OBJECT (demux, "Only managed to read %u bytes from file", - GST_BUFFER_SIZE (buffer)); + bsize); goto done; } } GST_BUFFER_OFFSET (buffer) = offset; - saved_size = GST_BUFFER_SIZE (buffer); - GST_BUFFER_SIZE (buffer) = tagsize; + saved_size = bsize; + gst_buffer_set_size (buffer, tagsize); newsize = tagsize; parse_ret = klass->parse_tag (demux, buffer, FALSE, &newsize, &new_tags); - GST_BUFFER_SIZE (buffer) = saved_size; + gst_buffer_set_size (buffer, saved_size); switch (parse_ret) { case GST_TAG_DEMUX_RESULT_OK: @@ -1015,6 +1035,7 @@ gst_tag_demux_pull_start_tag (GstTagDemux * demux, GstTagList ** tags) gboolean have_tag; gboolean res = FALSE; guint req, tagsize; + gsize bsize; klass = GST_TAG_DEMUX_CLASS (G_OBJECT_GET_CLASS (demux)); @@ -1037,9 +1058,11 @@ gst_tag_demux_pull_start_tag (GstTagDemux * demux, GstTagList ** tags) goto done; } - if (GST_BUFFER_SIZE (buffer) < klass->min_start_size) { + bsize = gst_buffer_get_size (buffer); + + if (bsize < klass->min_start_size) { GST_DEBUG_OBJECT (demux, "Only managed to read %u bytes from file - " - "no tag in this file", GST_BUFFER_SIZE (buffer)); + "no tag in this file", bsize); goto done; } @@ -1061,7 +1084,7 @@ gst_tag_demux_pull_start_tag (GstTagDemux * demux, GstTagList ** tags) /* Now pull the entire tag */ g_assert (tagsize >= klass->min_start_size); - if (GST_BUFFER_SIZE (buffer) < tagsize) { + if (bsize < tagsize) { gst_buffer_unref (buffer); buffer = NULL; @@ -1072,21 +1095,23 @@ gst_tag_demux_pull_start_tag (GstTagDemux * demux, GstTagList ** tags) goto done; } - if (GST_BUFFER_SIZE (buffer) < tagsize) { + bsize = gst_buffer_get_size (buffer); + + if (bsize < tagsize) { GST_DEBUG_OBJECT (demux, "Only managed to read %u bytes from file", - GST_BUFFER_SIZE (buffer)); + bsize); GST_ELEMENT_ERROR (demux, STREAM, DECODE, (_("Failed to read tag: not enough data")), (NULL)); goto done; } } - saved_size = GST_BUFFER_SIZE (buffer); - GST_BUFFER_SIZE (buffer) = tagsize; + saved_size = bsize; + gst_buffer_set_size (buffer, tagsize); newsize = tagsize; parse_ret = klass->parse_tag (demux, buffer, TRUE, &newsize, &new_tags); - GST_BUFFER_SIZE (buffer) = saved_size; + gst_buffer_set_size (buffer, saved_size); switch (parse_ret) { case GST_TAG_DEMUX_RESULT_OK: @@ -1272,6 +1297,7 @@ gst_tag_demux_read_range (GstTagDemux * demux, GstFlowReturn ret; guint64 in_offset; guint in_length; + gsize size; g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR); @@ -1294,7 +1320,7 @@ gst_tag_demux_read_range (GstTagDemux * demux, ret = gst_pad_pull_range (demux->priv->sinkpad, in_offset, in_length, buffer); if (ret == GST_FLOW_OK && *buffer) { - if (!gst_tag_demux_trim_buffer (demux, buffer)) + if (!gst_tag_demux_trim_buffer (demux, buffer, &size)) goto read_beyond_end; /* this should only happen in streaming mode */ diff --git a/gst-libs/gst/tag/gstvorbistag.c b/gst-libs/gst/tag/gstvorbistag.c index 0b3ad57..450061d 100644 --- a/gst-libs/gst/tag/gstvorbistag.c +++ b/gst-libs/gst/tag/gstvorbistag.c @@ -365,7 +365,8 @@ convert_failed: /** * gst_tag_list_from_vorbiscomment_buffer: - * @buffer: buffer to convert + * @data: data to convert + * @size: size of @data * @id_data: identification data at start of stream * @id_data_length: length of identification data * @vendor_string: pointer to a string that should take the vendor string @@ -378,7 +379,7 @@ convert_failed: * given vorbiscomment buffer or NULL on error. */ GstTagList * -gst_tag_list_from_vorbiscomment_buffer (const GstBuffer * buffer, +gst_tag_list_from_vorbiscomment (const guint8 * data, gsize size, const guint8 * id_data, const guint id_data_length, gchar ** vendor_string) { #define ADVANCE(x) G_STMT_START{ \ @@ -394,15 +395,12 @@ gst_tag_list_from_vorbiscomment_buffer (const GstBuffer * buffer, gchar *cur, *value; guint cur_size; guint iterations; - guint8 *data; - guint size, value_len; + guint value_len; GstTagList *list; - g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL); + g_return_val_if_fail (data != NULL, NULL); g_return_val_if_fail (id_data != NULL || id_data_length == 0, NULL); - data = GST_BUFFER_DATA (buffer); - size = GST_BUFFER_SIZE (buffer); list = gst_tag_list_new (); if (size < 11 || size <= id_data_length + 4) @@ -471,6 +469,8 @@ gst_tag_to_coverart (const GValue * image_value) GstStructure *mime_struct; GstBuffer *buffer; GList *l = NULL; + guint8 *data; + gsize size; g_return_val_if_fail (image_value != NULL, NULL); @@ -479,12 +479,14 @@ gst_tag_to_coverart (const GValue * image_value) mime_struct = gst_caps_get_structure (buffer->caps, 0); mime_type = gst_structure_get_name (mime_struct); + data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ); if (strcmp (mime_type, "text/uri-list") == 0) { /* URI reference */ - coverart_data = g_strndup ((gchar *) buffer->data, buffer->size); + coverart_data = g_strndup ((gchar *) data, size); } else { - coverart_data = g_base64_encode (buffer->data, buffer->size); + coverart_data = g_base64_encode (data, size); } + gst_buffer_unmap (buffer, data, size); data_result = g_strdup_printf ("COVERART=%s", coverart_data); mime_result = g_strdup_printf ("COVERARTMIME=%s", mime_type); @@ -647,7 +649,7 @@ gst_tag_list_to_vorbiscomment_buffer (const GstTagList * list, const gchar * vendor_string) { GstBuffer *buffer; - guint8 *data; + guint8 *data, *odata; guint i; GList *l; MyForEach my_data = { 0, 0, NULL }; @@ -663,8 +665,9 @@ gst_tag_list_to_vorbiscomment_buffer (const GstTagList * list, required_size = id_data_length + 4 + vendor_len + 4 + 1; gst_tag_list_foreach ((GstTagList *) list, write_one_tag, &my_data); required_size += 4 * my_data.count + my_data.data_count; + buffer = gst_buffer_new_and_alloc (required_size); - data = GST_BUFFER_DATA (buffer); + odata = data = gst_buffer_map (buffer, NULL, NULL, GST_MAP_WRITE); if (id_data_length > 0) { memcpy (data, id_data, id_data_length); data += id_data_length; @@ -692,6 +695,7 @@ gst_tag_list_to_vorbiscomment_buffer (const GstTagList * list, g_list_foreach (my_data.entries, (GFunc) g_free, NULL); g_list_free (my_data.entries); *data = 1; + gst_buffer_unmap (buffer, odata, required_size); return buffer; } diff --git a/gst-libs/gst/tag/gstxmptag.c b/gst-libs/gst/tag/gstxmptag.c index c3bc636..77b48cc 100644 --- a/gst-libs/gst/tag/gstxmptag.c +++ b/gst-libs/gst/tag/gstxmptag.c @@ -1132,11 +1132,11 @@ read_one_tag (GstTagList * list, const gchar * tag, XmpTag * xmptag, * Since: 0.10.29 */ GstTagList * -gst_tag_list_from_xmp_buffer (const GstBuffer * buffer) +gst_tag_list_from_xmp_buffer (GstBuffer * buffer) { GstTagList *list = NULL; - const gchar *xps, *xp1, *xp2, *xpe, *ns, *ne; - guint len, max_ft_len; + gchar *xps, *xp1, *xp2, *xpe, *ns, *ne; + gsize len, max_ft_len; gboolean in_tag; gchar *part, *pp; guint i; @@ -1157,10 +1157,10 @@ gst_tag_list_from_xmp_buffer (const GstBuffer * buffer) xmp_tags_initialize (); g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL); - g_return_val_if_fail (GST_BUFFER_SIZE (buffer) > 0, NULL); - xps = (const gchar *) GST_BUFFER_DATA (buffer); - len = GST_BUFFER_SIZE (buffer); + xps = gst_buffer_map (buffer, &len, NULL, GST_MAP_READ); + g_return_val_if_fail (len > 0, NULL); + xpe = &xps[len + 1]; /* check header and footer */ @@ -1365,6 +1365,8 @@ gst_tag_list_from_xmp_buffer (const GstBuffer * buffer) } g_free (part); + gst_buffer_unmap (buffer, xps, len); + return list; /* Errors */ @@ -1530,53 +1532,57 @@ GstBuffer * gst_tag_list_to_xmp_buffer (const GstTagList * list, gboolean read_only) { GstBuffer *buffer = NULL; - GString *data = g_string_sized_new (4096); + GString *str = g_string_sized_new (4096); guint i; + gsize size; + gpointer data; xmp_tags_initialize (); g_return_val_if_fail (GST_IS_TAG_LIST (list), NULL); /* xmp header */ - g_string_append (data, + g_string_append (str, "\n"); - g_string_append (data, + g_string_append (str, "\n"); - g_string_append (data, + g_string_append (str, "\n"); - g_string_append (data, "\n"); + g_string_append (str, ">\n"); + g_string_append (str, "\n"); /* iterate the taglist */ - gst_tag_list_foreach (list, write_one_tag, data); + gst_tag_list_foreach (list, write_one_tag, str); /* xmp footer */ - g_string_append (data, "\n"); - g_string_append (data, "\n"); - g_string_append (data, "\n"); + g_string_append (str, "\n"); + g_string_append (str, "\n"); + g_string_append (str, "\n"); if (!read_only) { /* the xmp spec recommand to add 2-4KB padding for in-place editable xmp */ guint i; for (i = 0; i < 32; i++) { - g_string_append (data, " " " " + g_string_append (str, " " " " " " " " "\n"); } } - g_string_append_printf (data, "\n", + g_string_append_printf (str, "\n", (read_only ? 'r' : 'w')); + size = str->len + 1; + data = g_string_free (str, FALSE); + buffer = gst_buffer_new (); - GST_BUFFER_SIZE (buffer) = data->len + 1; - GST_BUFFER_DATA (buffer) = (guint8 *) g_string_free (data, FALSE); - GST_BUFFER_MALLOCDATA (buffer) = GST_BUFFER_DATA (buffer); + gst_buffer_take_memory (buffer, + gst_memory_new_wrapped (0, data, g_free, size, 0, size)); return buffer; } diff --git a/gst-libs/gst/tag/tag.h b/gst-libs/gst/tag/tag.h index 15906df..10ae2ee 100644 --- a/gst-libs/gst/tag/tag.h +++ b/gst-libs/gst/tag/tag.h @@ -445,7 +445,8 @@ GList * gst_tag_to_vorbis_comments (const GstTagLis const gchar * tag); /* functions to convert GstBuffers with vorbiscomment contents to GstTagLists and back */ -GstTagList * gst_tag_list_from_vorbiscomment_buffer (const GstBuffer * buffer, +GstTagList * gst_tag_list_from_vorbiscomment (const guint8 * data, + gsize size, const guint8 * id_data, const guint id_data_length, gchar ** vendor_string); @@ -471,7 +472,7 @@ gboolean gst_tag_list_add_id3_image (GstTagList * tag_list, guint id3_picture_type); /* functions to convert GstBuffers with xmp packets contents to GstTagLists and back */ -GstTagList * gst_tag_list_from_xmp_buffer (const GstBuffer * buffer); +GstTagList * gst_tag_list_from_xmp_buffer (GstBuffer * buffer); GstBuffer * gst_tag_list_to_xmp_buffer (const GstTagList * list, gboolean read_only); @@ -482,12 +483,12 @@ GstBuffer * gst_tag_list_to_exif_buffer (const GstTagList * taglist, GstBuffer * gst_tag_list_to_exif_buffer_with_tiff_header (const GstTagList * taglist); -GstTagList * gst_tag_list_from_exif_buffer (const GstBuffer * buffer, +GstTagList * gst_tag_list_from_exif_buffer (GstBuffer * buffer, gint byte_order, guint32 base_offset); GstTagList * gst_tag_list_from_exif_buffer_with_tiff_header ( - const GstBuffer * buffer); + GstBuffer * buffer); /* other tag-related functions */ diff --git a/gst-libs/gst/tag/tags.c b/gst-libs/gst/tag/tags.c index 9521821..6dbddf2 100644 --- a/gst-libs/gst/tag/tags.c +++ b/gst-libs/gst/tag/tags.c @@ -553,10 +553,9 @@ gst_tag_image_data_to_image_buffer (const guint8 * image_data, guint image_data_len, GstTagImageType image_type) { const gchar *name; - GstBuffer *image; - GstCaps *caps; + guint8 *data; g_return_val_if_fail (image_data != NULL, NULL); g_return_val_if_fail (image_data_len > 0, NULL); @@ -565,14 +564,14 @@ gst_tag_image_data_to_image_buffer (const guint8 * image_data, GST_DEBUG ("image data len: %u bytes", image_data_len); /* allocate space for a NUL terminator for an uri too */ - image = gst_buffer_try_new_and_alloc (image_data_len + 1); - if (image == NULL) { - GST_WARNING ("failed to allocate buffer of %d for image", image_data_len); - return NULL; - } + image = gst_buffer_new_and_alloc (image_data_len + 1); + if (image == NULL) + goto alloc_failed; - memcpy (GST_BUFFER_DATA (image), image_data, image_data_len); - GST_BUFFER_DATA (image)[image_data_len] = '\0'; + data = gst_buffer_map (image, NULL, NULL, GST_MAP_WRITE); + memcpy (data, image_data, image_data_len); + data[image_data_len] = '\0'; + gst_buffer_unmap (image, data, image_data_len + 1); /* Find GStreamer media type, can't trust declared type */ caps = gst_type_find_helper_for_buffer (NULL, image, NULL); @@ -596,7 +595,7 @@ gst_tag_image_data_to_image_buffer (const guint8 * image_data, * to keep the original size of the image */ if (!g_str_equal (name, "text/uri-list")) - GST_BUFFER_SIZE (image) = image_data_len; + gst_buffer_set_size (image, image_data_len); if (image_type != GST_TAG_IMAGE_TYPE_NONE) { GST_LOG ("Setting image type: %d", image_type); @@ -623,4 +622,11 @@ error: gst_caps_unref (caps); return NULL; } +alloc_failed: + { + GST_WARNING ("failed to allocate buffer of %d for image", image_data_len); + gst_buffer_unref (image); + return NULL; + } + } -- 2.7.4