summaryrefslogtreecommitdiffstats
path: root/ext/metadata
diff options
context:
space:
mode:
authorEdgard Lima <edgard.lima@indt.org.br>2007-11-19 22:09:36 +0000
committerEdgard Lima <edgard.lima@indt.org.br>2007-11-19 22:09:36 +0000
commitac04e0124b18beb8fa0240479d284ec6383ebcc0 (patch)
treee84ab61ed2d381d925449224a5e9542f4fec03e0 /ext/metadata
parent9662a211521a8deef1cbe06ad1052243e7573515 (diff)
downloadgst-plugins-bad-ac04e0124b18beb8fa0240479d284ec6383ebcc0.tar.gz
gst-plugins-bad-ac04e0124b18beb8fa0240479d284ec6383ebcc0.tar.bz2
gst-plugins-bad-ac04e0124b18beb8fa0240479d284ec6383ebcc0.zip
Fixed buffer strip (safer wil pull and after seek).
Original commit message from CVS: Fixed buffer strip (safer wil pull and after seek).
Diffstat (limited to 'ext/metadata')
-rw-r--r--ext/metadata/gstmetadataparse.c247
-rw-r--r--ext/metadata/gstmetadataparse.h3
2 files changed, 125 insertions, 125 deletions
diff --git a/ext/metadata/gstmetadataparse.c b/ext/metadata/gstmetadataparse.c
index fec1cd60..f5afb477 100644
--- a/ext/metadata/gstmetadataparse.c
+++ b/ext/metadata/gstmetadataparse.c
@@ -163,11 +163,10 @@ static void gst_metadata_parse_send_tags (GstMetadataParse * filter);
static gboolean gst_metadata_parse_activate (GstPad * pad);
-static gboolean
-gst_metadata_parse_get_strip_range (gint64 * boffset, guint32 * bsize,
+static int
+gst_metadata_parse_get_strip_seg (const gint64 offset, guint32 size,
const gint64 seg_offset, const guint32 seg_size,
- gint64 * toffset, guint32 * tsize, gint64 * ioffset);
-
+ guint32 * boffset, guint32 * bsize, guint32 * seg_binter);
static gboolean
gst_metadata_parse_strip_buffer (GstMetadataParse * filter, gint64 offset,
GstBuffer ** buf);
@@ -444,10 +443,13 @@ gst_metadata_parse_src_event (GstPad * pad, GstEvent * event)
case GST_FORMAT_PERCENT:
if (filter->duration < 0)
goto done;
+ start = start * filter->duration / 100;
+ stop = stop * filter->duration / 100;
break;
default:
goto done;
}
+ format = GST_FORMAT_BYTES;
if (start_type == GST_SEEK_TYPE_CUR)
start = filter->offset + start;
@@ -565,9 +567,12 @@ gst_metadata_parse_init_members (GstMetadataParse * filter)
filter->iptc = TRUE;
filter->xmp = TRUE;
- memset (filter->seg_offset, 0x00, sizeof (filter->seg_offset[0]) * 3);
+ memset (filter->seg_offset_orig, 0x00,
+ sizeof (filter->seg_offset_orig[0]) * 3);
memset (filter->seg_size, 0x00, sizeof (filter->seg_size[0]) * 3);
+ memset (filter->seg_inject_offset, 0x00,
+ sizeof (filter->seg_inject_offset[0]) * 3);
memset (filter->seg_inject_data, 0x00,
sizeof (filter->seg_inject_data[0]) * 3);
memset (filter->seg_inject_size, 0x00,
@@ -848,23 +853,24 @@ gst_metadata_parse_parse (GstMetadataParse * filter, const guint8 * buf,
filter->need_more_data = TRUE;
} else {
int i, j;
+ guint32 bytes_striped;
filter->num_segs = 0;
/* FIXME: better design for segments */
filter->seg_size[0] = filter->parse_data.exif.size;
- filter->seg_offset[0] = filter->parse_data.exif.offset;
+ filter->seg_offset_orig[0] = filter->parse_data.exif.offset;
filter->seg_inject_size[0] = filter->parse_data.exif.size_inject;
filter->seg_inject_data[0] = filter->parse_data.exif.buffer;
filter->seg_size[1] = filter->parse_data.iptc.size;
- filter->seg_offset[1] = filter->parse_data.iptc.offset;
+ filter->seg_offset_orig[1] = filter->parse_data.iptc.offset;
filter->seg_inject_size[1] = filter->parse_data.iptc.size_inject;
filter->seg_inject_data[1] = filter->parse_data.iptc.buffer;
filter->seg_size[2] = filter->parse_data.xmp.size;
- filter->seg_offset[2] = filter->parse_data.xmp.offset;
+ filter->seg_offset_orig[2] = filter->parse_data.xmp.offset;
filter->seg_inject_size[2] = filter->parse_data.xmp.size_inject;
filter->seg_inject_data[2] = filter->parse_data.xmp.buffer;
@@ -882,7 +888,7 @@ gst_metadata_parse_parse (GstMetadataParse * filter, const guint8 * buf,
for (j = i + 1; j < 3; ++j) {
if (filter->seg_size[j])
if (filter->seg_size[min] == 0
- || filter->seg_offset[j] < filter->seg_offset[min])
+ || filter->seg_offset_orig[j] < filter->seg_offset_orig[min])
min = j;
}
if (min != i) {
@@ -890,13 +896,13 @@ gst_metadata_parse_parse (GstMetadataParse * filter, const guint8 * buf,
guint32 aux_size;
guint8 *aux_data;
- aux_offset = filter->seg_offset[i];
+ aux_offset = filter->seg_offset_orig[i];
aux_size = filter->seg_size[i];
- filter->seg_offset[i] = filter->seg_offset[min];
+ filter->seg_offset_orig[i] = filter->seg_offset_orig[min];
filter->seg_size[i] = filter->seg_size[min];
- filter->seg_offset[min] = aux_offset;
+ filter->seg_offset_orig[min] = aux_offset;
filter->seg_size[min] = aux_size;
aux_size = filter->seg_inject_size[i];
@@ -909,6 +915,15 @@ gst_metadata_parse_parse (GstMetadataParse * filter, const guint8 * buf,
}
}
+ bytes_striped = 0;
+
+ /* calculate the new position off injected chunks */
+ for (i = 0; i < filter->num_segs; ++i) {
+ filter->seg_inject_offset[i] =
+ filter->seg_offset_orig[i] - bytes_striped;
+ bytes_striped += filter->seg_size[i] - filter->seg_inject_size[i];
+ }
+
}
filter->state = MT_STATE_PARSED;
@@ -1145,68 +1160,77 @@ done:
}
/*
- * Returns FALSE if nothing has stripped, TRUE if otherwise
+ * offset - offset of buffer in original stream
+ * size - size of buffer
+ * seg_offset - offset of segment in original stream
+ * seg_size - size of segment
+ * boffset - offset inside buffer where segment starts (-1 for no intersection)
+ * bsize - size of intersection
+ * seg_binter - if segment start inside buffer is zero. if segment start before
+ * buffer and intersect, it is the offset inside segment.
+ *
+ * ret:
+ * -1 - segment before buffer
+ * 0 - segment intersects
+ * 1 - segment after buffer
*/
-static gboolean
-gst_metadata_parse_get_strip_range (gint64 * boffset, guint32 * bsize,
+static int
+gst_metadata_parse_get_strip_seg (const gint64 offset, guint32 size,
const gint64 seg_offset, const guint32 seg_size,
- gint64 * toffset, guint32 * tsize, gint64 * ioffset)
+ guint32 * boffset, guint32 * bsize, guint32 * seg_binter)
{
+ int ret = -1;
- gboolean ret = FALSE;
-
- if (seg_size == 0 || *bsize == 0)
- goto done;
+ *boffset = -1;
+ *bsize = 0;
+ *seg_binter = -1;
- /* segment after buffer */
- if (seg_offset > *boffset + *bsize) {
- *bsize = 0;
+ /* all segment after buffer */
+ if (seg_offset >= offset + size) {
+ ret = 1;
goto done;
}
- if (seg_offset < *boffset) {
+ if (seg_offset < offset) {
/* segment start somewhere before buffer */
- guint32 cut_size;
/* all segment before buffer */
- if (seg_offset + seg_size <= *boffset) {
- *tsize = *bsize;
- *bsize = 0;
- *toffset = *boffset;
+ if (seg_offset + seg_size <= offset) {
+ ret = -1;
goto done;
}
- cut_size = seg_size - (*boffset - seg_offset);
+ *seg_binter = offset - seg_offset;
+ *boffset = 0;
- if (cut_size >= *bsize) {
- /* all buffer striped out */
- *bsize = 0;
- *tsize = 0;
+ /* FIXME : optimize to >= size -> = size */
+ if (seg_offset + seg_size >= offset + size) {
+ /* segment cover all buffer */
+ *bsize = size;
} else {
- /* just beginning buffers striped */
- *toffset = *boffset + cut_size;
- *tsize = *bsize - cut_size;
- *bsize = 0;
+ /* segment goes from start of buffer to somewhere before end */
+ *bsize = seg_size - *seg_binter;
}
+ ret = 0;
+
} else {
/* segment start somewhere into buffer */
- *ioffset = seg_offset;
- if (seg_offset + seg_size >= *boffset + *bsize) {
- /* strip just tail */
- *bsize = seg_offset - *boffset;
+ *boffset = seg_offset - offset;
+ *seg_binter = 0;
+
+ if (seg_offset + seg_size <= offset + size) {
+ /* all segment into buffer */
+ *bsize = seg_size;
} else {
- /* strip the middle */
- *toffset = seg_offset + seg_size;
- *tsize = *boffset + *bsize - seg_offset - seg_size;
- *bsize = seg_offset - *boffset;
+ *bsize = size - *boffset;
}
- }
+ ret = 0;
- ret = TRUE;
+ }
done:
@@ -1224,110 +1248,85 @@ gst_metadata_parse_strip_buffer (GstMetadataParse * filter, gint64 offset,
GstBuffer ** buf)
{
- gint64 boffset[3];
- guint32 bsize[3];
-
- gint64 toffset[3];
- guint32 tsize[3];
-
- gint64 ioffset[3];
+ const gint64 *seg_offset = filter->seg_offset_orig;
+ const guint32 *seg_size = filter->seg_size;
+ const guint32 *seg_inject_size = filter->seg_inject_size;
+ const guint8 **seg_inject_data = filter->seg_inject_data;
- const gint64 *seg_offset = filter->seg_offset;
+ const size = GST_BUFFER_SIZE (*buf);
- const guint32 *seg_size = filter->seg_size;
+ gint64 boffset[3];
+ guint32 bsize[3];
+ guint32 seg_binter[3];
int i;
gboolean ret = FALSE;
- guint32 new_size = 0;
if (filter->num_segs == 0)
goto done;
memset (bsize, 0x00, sizeof (bsize));
- memset (tsize, 0x00, sizeof (tsize));
for (i = 0; i < filter->num_segs; ++i) {
- ioffset[i] = -1;
- }
-
- boffset[0] = offset;
- new_size = bsize[0] = GST_BUFFER_SIZE (*buf);
- i = 0;
+ int res;
- for (i = 0; i < filter->num_segs; ++i) {
- guint32 striped_size;
+ res = gst_metadata_parse_get_strip_seg (offset, size,
+ seg_offset[i], seg_size[i], &boffset[i], &bsize[i], &seg_binter[i]);
- striped_size = bsize[i];
- if (gst_metadata_parse_get_strip_range (&boffset[i], &bsize[i],
- seg_offset[i], seg_size[i], &toffset[i], &tsize[i], &ioffset[i])) {
- ret = TRUE;
- new_size -= (striped_size - (bsize[i] + tsize[i]));
- }
- if (i + 1 < filter->num_segs) {
- if (tsize[i]) {
- boffset[i + 1] = toffset[i];
- bsize[i + 1] = GST_BUFFER_SIZE (*buf) - (toffset[i] - offset);
- tsize[i] = 0;
- } else {
- /* buffer already consumed */
- break;
- }
- }
- if (new_size == 0) {
- /* all buffer striped already */
+ /* segment is after size (segments are sorted) */
+ if (res > 0)
break;
- }
+ if (res == 0)
+ ret = TRUE;
}
/* segments must be sorted by offset to make this copy */
if (ret) {
- if (new_size == 0) {
- gst_buffer_unref (*buf);
- *buf = NULL;
- } else {
- GstBuffer *new_buf;
- guint8 *data;
- for (i = 0; i < filter->num_segs; ++i) {
- if (filter->seg_inject_size[i] == 0)
- ioffset[i] = -1;
- else
- new_size += filter->seg_inject_size[i];
- }
+ guint8 *data;
+ guint32 moved = 0;
- if (GST_BUFFER_SIZE (new_buf) < new_size) {
- /* FIXME: alloc more memory here */
- }
+ if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_READONLY)) {
+ GstBuffer *new_buf = gst_buffer_copy (*buf);
- /* FIXME: try to use buffer data in place */
- new_buf = gst_buffer_copy (*buf);
- data = GST_BUFFER_DATA (new_buf);
+ gst_buffer_unref (*buf);
+ *buf = new_buf;
+ GST_BUFFER_FLAG_UNSET (*buf, GST_BUFFER_FLAG_READONLY);
+ }
- GST_BUFFER_SIZE (new_buf) = new_size;
+ data = GST_BUFFER_DATA (*buf);
- for (i = 0; i < filter->num_segs; ++i) {
- if (bsize[i]) {
- memcpy (data,
- GST_BUFFER_DATA (*buf) + (boffset[i] - offset), bsize[i]);
- data += bsize[i];
- }
- if (ioffset[i] >= 0) {
- memcpy (data, filter->seg_inject_data[i], filter->seg_inject_size[i]);
- data += filter->seg_inject_size[i];
+ for (i = 0; i < filter->num_segs; ++i) {
+
+ /* intersect */
+ if (bsize[i]) {
+ /* has data to inject */
+ if (seg_inject_size[i]) {
+ /* has data to inject here */
+ if (seg_binter[i] < seg_inject_size[i]) {
+ const guint32 inject_size = seg_inject_size[i] - seg_binter[i];
+
+ memcpy (data + boffset[i], seg_inject_data[i] + seg_binter[i],
+ inject_size);
+ boffset[i] += inject_size;
+ bsize[i] -= inject_size;
+ }
}
- if (tsize[i]) {
- memcpy (data,
- GST_BUFFER_DATA (*buf) + (toffset[i] - offset), tsize[i]);
- data += tsize[i];
+ if (bsize[i]) {
+ /* if even inject there is still thing to remove */
+ memmove (data + boffset[i] - moved,
+ data + boffset[i] + bsize[i] - moved,
+ size - boffset[i] - bsize[i] + moved);
+ moved += bsize[i];
}
}
- gst_buffer_unref (*buf);
- *buf = new_buf;
- GST_BUFFER_FLAG_UNSET (*buf, GST_BUFFER_FLAG_READONLY);
+
}
- }
+ GST_BUFFER_SIZE (*buf) -= moved;
+
+ }
done:
@@ -1347,10 +1346,10 @@ gst_metadata_parse_translate_pos (GstMetadataParse * filter, gint64 pos,
*orig_pos = 0;
for (i = 0; i < filter->num_segs; ++i) {
- if (filter->seg_offset[i] > pos) {
+ if (filter->seg_offset_orig[i] > pos) {
break;
}
- *orig_pos += filter->seg_size[i];
+ *orig_pos += filter->seg_size[i] - filter->seg_inject_size[i];
}
*orig_pos += pos;
diff --git a/ext/metadata/gstmetadataparse.h b/ext/metadata/gstmetadataparse.h
index 11e6a52e..17d0fcb3 100644
--- a/ext/metadata/gstmetadataparse.h
+++ b/ext/metadata/gstmetadataparse.h
@@ -79,9 +79,10 @@ struct _GstMetadataParse
gboolean iptc;
gboolean xmp;
- gint64 seg_offset[3];
+ gint64 seg_offset_orig[3]; /* offset in chunk in original stream */
guint32 seg_size[3];
+ gint64 seg_inject_offset[3]; /* offset of chunk in resulting stream */
guint32 seg_inject_size[3];
guint8 * seg_inject_data[3];