summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--ext/metadata/gstmetadataparse.c200
-rw-r--r--ext/metadata/gstmetadataparse.h1
3 files changed, 196 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 397681fd..34a8fa95 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2007-11-19 Edgard Lima <edgard.lima@indt.org.br>
+
+ * ext/metadata/gstmetadataparse.c:
+ * ext/metadata/gstmetadataparse.h:
+ Strip out in pull mode also. Seek and Query functions added.
+
2007-11-18 Edgard Lima <edgard.lima@indt.org.br>
* ext/metadata/gstmetadataparse.c:
diff --git a/ext/metadata/gstmetadataparse.c b/ext/metadata/gstmetadataparse.c
index 43dbe6ad..fec1cd60 100644
--- a/ext/metadata/gstmetadataparse.c
+++ b/ext/metadata/gstmetadataparse.c
@@ -168,6 +168,18 @@ gst_metadata_parse_get_strip_range (gint64 * boffset, guint32 * bsize,
const gint64 seg_offset, const guint32 seg_size,
gint64 * toffset, guint32 * tsize, gint64 * ioffset);
+static gboolean
+gst_metadata_parse_strip_buffer (GstMetadataParse * filter, gint64 offset,
+ GstBuffer ** buf);
+
+static void
+gst_metadata_parse_translate_pos (GstMetadataParse * filter, gint64 pos,
+ gint64 * orig_pos);
+
+static const GstQueryType *gst_metadata_parse_get_query_types (GstPad * pad);
+
+static gboolean gst_metadata_parse_src_query (GstPad * pad, GstQuery * query);
+
static void
gst_metadata_parse_base_init (gpointer gclass)
{
@@ -253,6 +265,10 @@ gst_metadata_parse_init (GstMetadataParse * filter,
gst_pad_set_getcaps_function (filter->srcpad,
GST_DEBUG_FUNCPTR (gst_metadata_parse_get_caps));
gst_pad_set_event_function (filter->srcpad, gst_metadata_parse_src_event);
+ gst_pad_set_query_function (filter->srcpad,
+ GST_DEBUG_FUNCPTR (gst_metadata_parse_src_query));
+ gst_pad_set_query_type_function (filter->srcpad,
+ GST_DEBUG_FUNCPTR (gst_metadata_parse_get_query_types));
gst_pad_use_fixed_caps (filter->srcpad);
gst_pad_set_getrange_function (filter->srcpad, gst_metadata_parse_get_range);
gst_pad_set_activatepull_function (filter->srcpad,
@@ -406,11 +422,60 @@ gst_metadata_parse_src_event (GstPad * pad, GstEvent * event)
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEEK:
- if (filter->state != MT_STATE_PARSED) {
- /* FIXME: What to do here */
- ret = TRUE;
+ {
+ gdouble rate;
+ GstFormat format;
+ GstSeekFlags flags;
+ GstSeekType start_type;
+ gint64 start;
+ GstSeekType stop_type;
+ gint64 stop;
+
+ /* we don't know where are the chunks to be stripped before parse */
+ if (filter->state != MT_STATE_PARSED)
goto done;
+
+ gst_event_parse_seek (event, &rate, &format, &flags,
+ &start_type, &start, &stop_type, &stop);
+
+ switch (format) {
+ case GST_FORMAT_BYTES:
+ break;
+ case GST_FORMAT_PERCENT:
+ if (filter->duration < 0)
+ goto done;
+ break;
+ default:
+ goto done;
+ }
+
+ if (start_type == GST_SEEK_TYPE_CUR)
+ start = filter->offset + start;
+ else if (start_type == GST_SEEK_TYPE_END) {
+ if (filter->duration < 0)
+ goto done;
+ start = filter->duration + start;
}
+ start_type == GST_SEEK_TYPE_SET;
+
+ gst_metadata_parse_translate_pos (filter, start, &start);
+
+ if (stop_type == GST_SEEK_TYPE_CUR)
+ stop = filter->offset + stop;
+ else if (stop_type == GST_SEEK_TYPE_END) {
+ if (filter->duration < 0)
+ goto done;
+ stop = filter->duration + stop;
+ }
+ stop_type == GST_SEEK_TYPE_SET;
+
+ gst_metadata_parse_translate_pos (filter, stop, &stop);
+
+ gst_event_unref (event);
+ event = gst_event_new_seek (rate, format, flags,
+ start_type, start, stop_type, stop);
+
+ }
break;
default:
break;
@@ -516,6 +581,7 @@ gst_metadata_parse_init_members (GstMetadataParse * filter)
filter->next_size = 0;
filter->img_type = IMG_NONE;
filter->duration = -1;
+ filter->offset_orig = 0;
filter->offset = 0;
filter->state = MT_STATE_NULL;
filter->need_more_data = FALSE;
@@ -698,6 +764,59 @@ gst_metadata_parse_send_tags (GstMetadataParse * filter)
filter->need_send_tag = FALSE;
}
+static const GstQueryType *
+gst_metadata_parse_get_query_types (GstPad * pad)
+{
+ static const GstQueryType gst_metadata_parse_src_query_types[] = {
+ GST_QUERY_POSITION,
+ GST_QUERY_DURATION,
+ GST_QUERY_FORMATS,
+ 0
+ };
+
+ return gst_metadata_parse_src_query_types;
+}
+
+static gboolean
+gst_metadata_parse_src_query (GstPad * pad, GstQuery * query)
+{
+ gboolean ret = FALSE;
+ GstFormat format;
+ GstMetadataParse *filter = GST_METADATA_PARSE (gst_pad_get_parent (pad));
+
+ switch (GST_QUERY_TYPE (query)) {
+ case GST_QUERY_POSITION:
+ gst_query_parse_position (query, &format, NULL);
+
+ if (format == GST_FORMAT_BYTES) {
+ gst_query_set_position (query, GST_FORMAT_BYTES, filter->offset);
+ ret = TRUE;
+ }
+ break;
+ case GST_QUERY_DURATION:
+ gst_query_parse_duration (query, &format, NULL);
+
+ if (format == GST_FORMAT_BYTES) {
+ if (filter->duration >= 0) {
+ gst_query_set_duration (query, GST_FORMAT_BYTES, filter->duration);
+ ret = TRUE;
+ }
+ }
+ break;
+ case GST_QUERY_FORMATS:
+ gst_query_set_formats (query, 1, GST_FORMAT_BYTES);
+ ret = TRUE;
+ break;
+ default:
+ break;
+ }
+
+ gst_object_unref (filter);
+
+ return ret;
+
+}
+
/*
* return:
* -1 -> error
@@ -818,12 +937,19 @@ done:
* this function does the actual processing
*/
+/* FIXME */
+/* Current parse is just done before is pull mode could be activated */
+/* may be it is possible to parse in chain mode by doing some trick with gst-adapter */
+/* the pipeline below would be a test for that case */
+/* gst-launch-0.10 filesrc location=Exif.jpg ! queue ! metadataparse ! filesink location=gen3.jpg */
+
static GstFlowReturn
gst_metadata_parse_chain (GstPad * pad, GstBuffer * buf)
{
GstMetadataParse *filter = NULL;
GstFlowReturn ret = GST_FLOW_ERROR;
- guint32 buf_size;
+ guint32 buf_size = 0;
+ guint32 new_buf_size = 0;
filter = GST_METADATA_PARSE (gst_pad_get_parent (pad));
@@ -879,11 +1005,11 @@ gst_metadata_parse_chain (GstPad * pad, GstBuffer * buf)
}
buf_size = GST_BUFFER_SIZE (buf);
- gst_metadata_parse_strip_buffer (filter, &buf);
- filter->offset += buf_size;
+ gst_metadata_parse_strip_buffer (filter, filter->offset_orig, &buf);
if (buf) { /* may be all buffer has been striped */
gst_buffer_set_caps (buf, GST_PAD_CAPS (filter->srcpad));
+ new_buf_size = GST_BUFFER_SIZE (buf);
ret = gst_pad_push (filter->srcpad, buf);
buf = NULL; /* this function don't owner it anymore */
@@ -893,6 +1019,9 @@ gst_metadata_parse_chain (GstPad * pad, GstBuffer * buf)
done:
+ filter->offset_orig += buf_size;
+ filter->offset += new_buf_size;
+
if (buf) {
/* there was an error and buffer wasn't pushed */
gst_buffer_unref (buf);
@@ -960,6 +1089,19 @@ gst_metadata_parse_pull_range_parse (GstMetadataParse * filter)
} while (res > 0);
+ if (res == 0) {
+ int i;
+
+ filter->duration = duration;
+
+ for (i = 0; i < filter->num_segs; ++i) {
+
+ filter->duration -= (filter->seg_size[i] - filter->seg_inject_size[i]);
+
+ }
+
+ }
+
done:
return ret;
@@ -977,6 +1119,7 @@ gst_metadata_parse_activate (GstPad * pad)
if (!gst_pad_check_pull_range (pad) ||
!gst_pad_activate_pull (filter->sinkpad, TRUE)) {
+ /* FIXME: currently it is not possible to parse in chain. Fail here ? */
/* nothing to be done by now, activate push mode */
return gst_pad_activate_push (pad, TRUE);
}
@@ -1005,7 +1148,7 @@ done:
* Returns FALSE if nothing has stripped, TRUE if otherwise
*/
-gboolean
+static gboolean
gst_metadata_parse_get_strip_range (gint64 * boffset, guint32 * bsize,
const gint64 seg_offset, const guint32 seg_size,
gint64 * toffset, guint32 * tsize, gint64 * ioffset)
@@ -1076,8 +1219,9 @@ done:
* FALSE -> buffer unmodified
*/
-gboolean
-gst_metadata_parse_strip_buffer (GstMetadataParse * filter, GstBuffer ** buf)
+static gboolean
+gst_metadata_parse_strip_buffer (GstMetadataParse * filter, gint64 offset,
+ GstBuffer ** buf)
{
gint64 boffset[3];
@@ -1095,7 +1239,6 @@ gst_metadata_parse_strip_buffer (GstMetadataParse * filter, GstBuffer ** buf)
int i;
gboolean ret = FALSE;
guint32 new_size = 0;
- const gint64 offset = filter->offset;
if (filter->num_segs == 0)
goto done;
@@ -1192,11 +1335,35 @@ done:
}
+/*
+ * pos - position in stream striped
+ * orig_pos - position in original stream
+ */
+static void
+gst_metadata_parse_translate_pos (GstMetadataParse * filter, gint64 pos,
+ gint64 * orig_pos)
+{
+ int i;
+
+ *orig_pos = 0;
+ for (i = 0; i < filter->num_segs; ++i) {
+ if (filter->seg_offset[i] > pos) {
+ break;
+ }
+ *orig_pos += filter->seg_size[i];
+ }
+ *orig_pos += pos;
+
+}
+
static gboolean
gst_metadata_parse_get_range (GstPad * pad,
guint64 offset, guint size, GstBuffer ** buf)
{
GstMetadataParse *filter = NULL;
+ gboolean ret;
+ gint64 pos;
+ const gint64 saved_offset = offset + size;
filter = GST_METADATA_PARSE (GST_PAD_PARENT (pad));
@@ -1204,7 +1371,18 @@ gst_metadata_parse_get_range (GstPad * pad,
gst_metadata_parse_send_tags (filter);
}
- return gst_pad_pull_range (filter->sinkpad, offset, size, buf);
+ gst_metadata_parse_translate_pos (filter, offset + size - 1, &pos);
+ gst_metadata_parse_translate_pos (filter, offset, &offset);
+
+ ret = gst_pad_pull_range (filter->sinkpad, offset, 1 + pos - offset, buf);
+
+ if (ret == GST_FLOW_OK && *buf) {
+ gst_metadata_parse_strip_buffer (filter, offset, buf);
+ filter->offset_orig = pos;
+ filter->offset = saved_offset;
+ }
+
+ return ret;
}
diff --git a/ext/metadata/gstmetadataparse.h b/ext/metadata/gstmetadataparse.h
index dd5a031c..11e6a52e 100644
--- a/ext/metadata/gstmetadataparse.h
+++ b/ext/metadata/gstmetadataparse.h
@@ -96,6 +96,7 @@ struct _GstMetadataParse
guint32 next_size;
ImageType img_type;
+ gint64 offset_orig;
gint64 duration;
gint64 offset;