mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-18 15:51:11 +00:00
tags: port to new metadata and memory API
This commit is contained in:
parent
95f7fd8edf
commit
41025681bc
7 changed files with 253 additions and 155 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
GST_LOG ("Parsing exif tags with tiff header of size %u",
|
||||
GST_BUFFER_SIZE (buffer));
|
||||
data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
|
||||
|
||||
gst_byte_reader_init_from_buffer (&reader, buffer);
|
||||
GST_LOG ("Parsing exif tags with tiff header of size %u", size);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
"<?xpacket begin=\"\xEF\xBB\xBF\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>\n");
|
||||
g_string_append (data,
|
||||
g_string_append (str,
|
||||
"<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"GStreamer\">\n");
|
||||
g_string_append (data,
|
||||
g_string_append (str,
|
||||
"<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"");
|
||||
i = 0;
|
||||
while (ns_match[i].ns_prefix) {
|
||||
g_string_append_printf (data, " xmlns:%s=\"%s\"", ns_match[i].ns_prefix,
|
||||
g_string_append_printf (str, " xmlns:%s=\"%s\"", ns_match[i].ns_prefix,
|
||||
ns_match[i].ns_uri);
|
||||
i++;
|
||||
}
|
||||
g_string_append (data, ">\n");
|
||||
g_string_append (data, "<rdf:Description rdf:about=\"\">\n");
|
||||
g_string_append (str, ">\n");
|
||||
g_string_append (str, "<rdf:Description rdf:about=\"\">\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, "</rdf:Description>\n");
|
||||
g_string_append (data, "</rdf:RDF>\n");
|
||||
g_string_append (data, "</x:xmpmeta>\n");
|
||||
g_string_append (str, "</rdf:Description>\n");
|
||||
g_string_append (str, "</rdf:RDF>\n");
|
||||
g_string_append (str, "</x:xmpmeta>\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, "<?xpacket end=\"%c\"?>\n",
|
||||
g_string_append_printf (str, "<?xpacket end=\"%c\"?>\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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue