summaryrefslogtreecommitdiffstats
path: root/ext/metadata/gstbasemetadata.c
diff options
context:
space:
mode:
authorEdgard Lima <edgard.lima@indt.org.br>2008-01-30 12:56:51 +0000
committerEdgard Lima <edgard.lima@indt.org.br>2008-01-30 12:56:51 +0000
commit1159638102e1669bbf0e5f81fb89069b032a2410 (patch)
tree3ff42c1bae9a31b087f4db9d65881870624dfff9 /ext/metadata/gstbasemetadata.c
parent7460bb6d910201c1b97db893e1d5a0186366717e (diff)
downloadgst-plugins-bad-1159638102e1669bbf0e5f81fb89069b032a2410.tar.gz
gst-plugins-bad-1159638102e1669bbf0e5f81fb89069b032a2410.tar.bz2
gst-plugins-bad-1159638102e1669bbf0e5f81fb89069b032a2410.zip
Add documentation. Fix test app compilation. Fix pull mode.
Original commit message from CVS: Add documentation. Fix test app compilation. Fix pull mode.
Diffstat (limited to 'ext/metadata/gstbasemetadata.c')
-rw-r--r--ext/metadata/gstbasemetadata.c177
1 files changed, 106 insertions, 71 deletions
diff --git a/ext/metadata/gstbasemetadata.c b/ext/metadata/gstbasemetadata.c
index 6d826607..92a13fa8 100644
--- a/ext/metadata/gstbasemetadata.c
+++ b/ext/metadata/gstbasemetadata.c
@@ -159,7 +159,8 @@ gst_base_metadata_parse (GstBaseMetadata * filter, const guint8 * buf,
static gboolean
gst_base_metadata_strip_push_buffer (GstBaseMetadata * base,
- gint64 offset_orig, GstBuffer ** prepend, GstBuffer ** buf);
+ const gint64 offset_orig, GstBuffer ** prepend, GstBuffer ** buf,
+ gboolean inject_begin);
static int
gst_base_metadata_buf_get_intersection_seg (const gint64 offset, guint32 size,
@@ -168,7 +169,7 @@ gst_base_metadata_buf_get_intersection_seg (const gint64 offset, guint32 size,
static gboolean
gst_base_metadata_translate_pos_to_orig (GstBaseMetadata * base,
- gint64 pos, gint64 * orig_pos, GstBuffer ** buf);
+ gint64 pos, gint64 * orig_pos, GstBuffer ** buf, guint32 max_size);
static gboolean gst_base_metadata_calculate_offsets (GstBaseMetadata * base);
@@ -639,6 +640,7 @@ done:
* beginning og @buf
* @buf: a pointer to a buffer that will be modified (data striped/injected or
* prepended)
+ * @inject_begin: is TRUE can inject a chunk start exactly in @offset_orig
*
* Strip bytes from @buf that are part of some chunk that will be striped. Add
* a whole injected chunk if some inject chunk starts into the buffer. Prepend
@@ -658,7 +660,8 @@ done:
static gboolean
gst_base_metadata_strip_push_buffer (GstBaseMetadata * base,
- gint64 offset_orig, GstBuffer ** prepend, GstBuffer ** buf)
+ const gint64 offset_orig, GstBuffer ** prepend, GstBuffer ** buf,
+ gboolean inject_begin)
{
MetadataChunk *strip = META_DATA_STRIP_CHUNKS (base->metadata).chunk;
MetadataChunk *inject = META_DATA_INJECT_CHUNKS (base->metadata).chunk;
@@ -692,11 +695,13 @@ gst_base_metadata_strip_push_buffer (GstBaseMetadata * base,
int res;
if (inject[i].offset_orig >= offset_orig) {
- if (inject[i].offset_orig < offset_orig + size_buf_in) {
- injected_bytes += inject[i].size;
- } else {
- /* segment is after size (segments are sorted) */
- break;
+ if (G_LIKELY (inject_begin || inject[i].offset_orig > offset_orig)) {
+ if (inject[i].offset_orig < offset_orig + size_buf_in) {
+ injected_bytes += inject[i].size;
+ } else {
+ /* segment is after size (segments are sorted) */
+ break;
+ }
}
}
}
@@ -846,20 +851,22 @@ inject:
original buffer */
if (inject[i].offset_orig >= offset_orig) {
- if (inject[i].offset_orig <
- offset_orig + size_buf_in + striped_bytes - injected_bytes) {
- /* insert */
- guint32 buf_off =
- inject[i].offset_orig - offset_orig - striped_so_far +
- injected_bytes;
- memmove (data + buf_off + inject[i].size, data + buf_off,
- size_buf_in - buf_off);
- memcpy (data + buf_off, inject[i].data, inject[i].size);
- injected_bytes += inject[i].size;
- size_buf_in += inject[i].size;
- } else {
- /* segment is after size (segments are sorted) */
- break;
+ if (G_LIKELY (inject_begin || inject[i].offset_orig > offset_orig)) {
+ if (inject[i].offset_orig <
+ offset_orig + size_buf_in + striped_bytes - injected_bytes) {
+ /* insert */
+ guint32 buf_off =
+ inject[i].offset_orig - offset_orig - striped_so_far +
+ injected_bytes;
+ memmove (data + buf_off + inject[i].size, data + buf_off,
+ size_buf_in - buf_off);
+ memcpy (data + buf_off, inject[i].data, inject[i].size);
+ injected_bytes += inject[i].size;
+ size_buf_in += inject[i].size;
+ } else {
+ /* segment is after size (segments are sorted) */
+ break;
+ }
}
}
}
@@ -988,6 +995,7 @@ done:
* @orig_pos: position in original stream
* @buf: if not NULL, will have data that starts at some point into a injected
* chunk
+ * @max_size: the maximum size to allocate to @buf. pass 0 if don't care
*
* Given a position in output stream (@pos), returns the position in original
* stream (@orig_pos) that contains the same data. If @pos is into a injected
@@ -1006,7 +1014,7 @@ done:
static gboolean
gst_base_metadata_translate_pos_to_orig (GstBaseMetadata * base,
- gint64 pos, gint64 * orig_pos, GstBuffer ** buf)
+ gint64 pos, gint64 * orig_pos, GstBuffer ** buf, guint32 max_size)
{
MetadataChunk *strip = META_DATA_STRIP_CHUNKS (base->metadata).chunk;
MetadataChunk *inject = META_DATA_INJECT_CHUNKS (base->metadata).chunk;
@@ -1014,9 +1022,11 @@ gst_base_metadata_translate_pos_to_orig (GstBaseMetadata * base,
const gsize inject_len = META_DATA_INJECT_CHUNKS (base->metadata).len;
const gint64 duration_orig = base->duration_orig;
const gint64 duration = base->duration;
+ gboolean ret = TRUE;
+ const gint64 saved_pos = pos;
int i;
- gboolean ret = TRUE;
+
guint64 new_buf_size = 0;
guint64 injected_before = 0;
@@ -1032,56 +1042,67 @@ gst_base_metadata_translate_pos_to_orig (GstBaseMetadata * base,
/* calculate for injected */
/* just calculate size */
- *orig_pos = pos; /* save pos */
for (i = 0; i < inject_len; ++i) {
- /* check if pos in inside chunk */
- if (inject[i].offset <= pos) {
+ if (pos >= inject[i].offset) {
if (pos < inject[i].offset + inject[i].size) {
- /* orig pos points after insert chunk */
- new_buf_size += inject[i].size;
- /* put pos after current chunk */
- pos = inject[i].offset + inject[i].size;
+ /* pos is inside the chunk */
+ const guint32 offset_in_chunk = pos - inject[i].offset;
+
ret = FALSE;
+ pos = inject[i].offset + inject[i].size; /* put pos just after chunk */
+ new_buf_size += inject[i].size - offset_in_chunk;
+ /* we still continue, 'cause the next chunk could be just after this */
} else {
/* in case pos is not inside a injected chunk */
injected_before += inject[i].size;
}
} else {
+ /* pos is before the chunk */
break;
}
}
/* alloc buffer and calcute original pos */
- if (buf && ret == FALSE) {
- guint8 *data;
+ if (ret == FALSE) {
- if (*buf)
- gst_buffer_unref (*buf);
- *buf = gst_buffer_new_and_alloc (new_buf_size);
- data = GST_BUFFER_DATA (*buf);
- pos = *orig_pos; /* recover saved pos */
- for (i = 0; i < inject_len; ++i) {
- if (inject[i].offset > pos) {
- break;
- }
- if (inject[i].offset <= pos && pos < inject[i].offset + inject[i].size) {
- memcpy (data, inject[i].data, inject[i].size);
- data += inject[i].size;
- pos = inject[i].offset + inject[i].size;
- /* out position after insert chunk orig */
- *orig_pos = inject[i].offset_orig + inject[i].size;
+ *orig_pos = pos;
+
+ if (buf) {
+ guint8 *data;
+
+ if (max_size > 0)
+ if (new_buf_size > max_size)
+ new_buf_size = max_size;
+
+ if (*buf)
+ gst_buffer_unref (*buf);
+ *buf = gst_buffer_new_and_alloc (new_buf_size);
+ data = GST_BUFFER_DATA (*buf);
+ pos = saved_pos;
+ for (i = 0; i < inject_len && new_buf_size > 0; ++i) {
+ if (inject[i].offset > pos) {
+ break;
+ }
+ if (pos < inject[i].offset + inject[i].size) {
+ const guint32 offset = pos - inject[i].offset;
+ guint32 size = inject[i].size - offset;
+
+ if (size > new_buf_size)
+ size = new_buf_size;
+ memcpy (data, inject[i].data + offset, size);
+ data += size;
+ pos = inject[i].offset + inject[i].size;
+ new_buf_size -= size;
+ }
}
}
- }
- if (ret == FALSE) {
- /* if it inside a injected is already done */
goto done;
}
/* calculate for striped */
- *orig_pos = pos - injected_before;
+ *orig_pos = saved_pos - injected_before;
for (i = 0; i < strip_len; ++i) {
if (strip[i].offset_orig > pos) {
break;
@@ -1479,7 +1500,7 @@ gst_base_metadata_src_event (GstPad * pad, GstEvent * event)
striped/injected buffer in next 'chain' calling */
filter->offset = start;
gst_base_metadata_translate_pos_to_orig (filter, start, &start,
- &filter->prepend_buffer);
+ &filter->prepend_buffer, 0);
filter->offset_orig = start;
if (stop_type == GST_SEEK_TYPE_CUR)
@@ -1491,7 +1512,7 @@ gst_base_metadata_src_event (GstPad * pad, GstEvent * event)
}
stop_type == GST_SEEK_TYPE_SET;
- gst_base_metadata_translate_pos_to_orig (filter, stop, &stop, NULL);
+ gst_base_metadata_translate_pos_to_orig (filter, stop, &stop, NULL, 0);
gst_event_unref (event);
event = gst_event_new_seek (rate, format, flags,
@@ -1569,6 +1590,7 @@ gst_base_metadata_get_range (GstPad * pad,
guint size_orig;
GstBuffer *prepend = NULL;
gboolean need_append = FALSE;
+ gboolean into_inject;
filter = GST_BASE_METADATA (GST_PAD_PARENT (pad));
@@ -1583,34 +1605,45 @@ gst_base_metadata_get_range (GstPad * pad,
size_orig = size;
- gst_base_metadata_translate_pos_to_orig (filter, offset,
- &offset_orig, &prepend);
+ into_inject = !gst_base_metadata_translate_pos_to_orig (filter, offset,
+ &offset_orig, &prepend, size);
+
+ if (into_inject) {
+ size_orig = GST_BUFFER_SIZE (prepend) < size_orig ?
+ size_orig - GST_BUFFER_SIZE (prepend) : 0;
+ }
+
+ if (size_orig == 0) {
+ /* enough data in prepend */
+ *buf = prepend;
+ goto done;
+ }
- if (size > 1) {
+ if (size_orig > 1) {
gint64 pos;
pos = offset + size - 1;
- gst_base_metadata_translate_pos_to_orig (filter, pos, &pos, NULL);
+ into_inject = gst_base_metadata_translate_pos_to_orig (filter, pos, &pos,
+ NULL, 0);
size_orig = pos + 1 - offset_orig;
}
- if (size_orig) {
-
- ret = gst_pad_pull_range (filter->sinkpad, offset_orig, size_orig, buf);
+ ret = gst_pad_pull_range (filter->sinkpad, offset_orig, size_orig, buf);
- if (ret == GST_FLOW_OK && *buf) {
- gst_base_metadata_strip_push_buffer (filter, offset_orig, &prepend, buf);
-
- if (GST_BUFFER_SIZE (*buf) < size) {
- /* need append */
- need_append = TRUE;
- }
+ if (ret == GST_FLOW_OK && *buf) {
+ gst_base_metadata_strip_push_buffer (filter, offset_orig, &prepend, buf,
+ FALSE);
+ if (GST_BUFFER_SIZE (*buf) < size) {
+ /* need append */
+ need_append = TRUE;
+ } else {
+ /* hide extra bytes */
+ GST_BUFFER_SIZE (*buf) = size;
}
- } else {
- *buf = prepend;
}
+
done:
if (need_append) {
@@ -1715,7 +1748,7 @@ gst_base_metadata_chain (GstPad * pad, GstBuffer * buf)
buf_size = GST_BUFFER_SIZE (buf);
gst_base_metadata_strip_push_buffer (filter, filter->offset_orig,
- &filter->prepend_buffer, &buf);
+ &filter->prepend_buffer, &buf, TRUE);
if (buf) { /* may be all buffer has been striped */
gst_buffer_set_caps (buf, GST_PAD_CAPS (filter->srcpad));
@@ -1848,6 +1881,7 @@ gst_base_metadata_src_query (GstPad * pad, GstQuery * query)
gst_query_set_position (query, GST_FORMAT_BYTES, filter->offset);
ret = TRUE;
}
+
break;
case GST_QUERY_DURATION:
@@ -1864,6 +1898,7 @@ gst_base_metadata_src_query (GstPad * pad, GstQuery * query)
ret = TRUE;
}
}
+
break;
case GST_QUERY_FORMATS:
gst_query_set_formats (query, 1, GST_FORMAT_BYTES);