mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-08 21:28:45 +00:00
Strip out in pull mode also. Seek and Query functions added.
Original commit message from CVS: Strip out in pull mode also. Seek and Query functions added.
This commit is contained in:
parent
a7a580dd58
commit
dcb8f93e76
3 changed files with 196 additions and 11 deletions
|
@ -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>
|
2007-11-18 Edgard Lima <edgard.lima@indt.org.br>
|
||||||
|
|
||||||
* ext/metadata/gstmetadataparse.c:
|
* 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,
|
const gint64 seg_offset, const guint32 seg_size,
|
||||||
gint64 * toffset, guint32 * tsize, gint64 * ioffset);
|
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
|
static void
|
||||||
gst_metadata_parse_base_init (gpointer gclass)
|
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_pad_set_getcaps_function (filter->srcpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_metadata_parse_get_caps));
|
GST_DEBUG_FUNCPTR (gst_metadata_parse_get_caps));
|
||||||
gst_pad_set_event_function (filter->srcpad, gst_metadata_parse_src_event);
|
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_use_fixed_caps (filter->srcpad);
|
||||||
gst_pad_set_getrange_function (filter->srcpad, gst_metadata_parse_get_range);
|
gst_pad_set_getrange_function (filter->srcpad, gst_metadata_parse_get_range);
|
||||||
gst_pad_set_activatepull_function (filter->srcpad,
|
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)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_SEEK:
|
case GST_EVENT_SEEK:
|
||||||
if (filter->state != MT_STATE_PARSED) {
|
{
|
||||||
/* FIXME: What to do here */
|
gdouble rate;
|
||||||
ret = TRUE;
|
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;
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -516,6 +581,7 @@ gst_metadata_parse_init_members (GstMetadataParse * filter)
|
||||||
filter->next_size = 0;
|
filter->next_size = 0;
|
||||||
filter->img_type = IMG_NONE;
|
filter->img_type = IMG_NONE;
|
||||||
filter->duration = -1;
|
filter->duration = -1;
|
||||||
|
filter->offset_orig = 0;
|
||||||
filter->offset = 0;
|
filter->offset = 0;
|
||||||
filter->state = MT_STATE_NULL;
|
filter->state = MT_STATE_NULL;
|
||||||
filter->need_more_data = FALSE;
|
filter->need_more_data = FALSE;
|
||||||
|
@ -698,6 +764,59 @@ gst_metadata_parse_send_tags (GstMetadataParse * filter)
|
||||||
filter->need_send_tag = FALSE;
|
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:
|
* return:
|
||||||
* -1 -> error
|
* -1 -> error
|
||||||
|
@ -818,12 +937,19 @@ done:
|
||||||
* this function does the actual processing
|
* 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
|
static GstFlowReturn
|
||||||
gst_metadata_parse_chain (GstPad * pad, GstBuffer * buf)
|
gst_metadata_parse_chain (GstPad * pad, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
GstMetadataParse *filter = NULL;
|
GstMetadataParse *filter = NULL;
|
||||||
GstFlowReturn ret = GST_FLOW_ERROR;
|
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));
|
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);
|
buf_size = GST_BUFFER_SIZE (buf);
|
||||||
gst_metadata_parse_strip_buffer (filter, &buf);
|
gst_metadata_parse_strip_buffer (filter, filter->offset_orig, &buf);
|
||||||
filter->offset += buf_size;
|
|
||||||
|
|
||||||
if (buf) { /* may be all buffer has been striped */
|
if (buf) { /* may be all buffer has been striped */
|
||||||
gst_buffer_set_caps (buf, GST_PAD_CAPS (filter->srcpad));
|
gst_buffer_set_caps (buf, GST_PAD_CAPS (filter->srcpad));
|
||||||
|
new_buf_size = GST_BUFFER_SIZE (buf);
|
||||||
|
|
||||||
ret = gst_pad_push (filter->srcpad, buf);
|
ret = gst_pad_push (filter->srcpad, buf);
|
||||||
buf = NULL; /* this function don't owner it anymore */
|
buf = NULL; /* this function don't owner it anymore */
|
||||||
|
@ -893,6 +1019,9 @@ gst_metadata_parse_chain (GstPad * pad, GstBuffer * buf)
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
|
||||||
|
filter->offset_orig += buf_size;
|
||||||
|
filter->offset += new_buf_size;
|
||||||
|
|
||||||
if (buf) {
|
if (buf) {
|
||||||
/* there was an error and buffer wasn't pushed */
|
/* there was an error and buffer wasn't pushed */
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
@ -960,6 +1089,19 @@ gst_metadata_parse_pull_range_parse (GstMetadataParse * filter)
|
||||||
|
|
||||||
} while (res > 0);
|
} 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:
|
done:
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -977,6 +1119,7 @@ gst_metadata_parse_activate (GstPad * pad)
|
||||||
|
|
||||||
if (!gst_pad_check_pull_range (pad) ||
|
if (!gst_pad_check_pull_range (pad) ||
|
||||||
!gst_pad_activate_pull (filter->sinkpad, TRUE)) {
|
!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 */
|
/* nothing to be done by now, activate push mode */
|
||||||
return gst_pad_activate_push (pad, TRUE);
|
return gst_pad_activate_push (pad, TRUE);
|
||||||
}
|
}
|
||||||
|
@ -1005,7 +1148,7 @@ done:
|
||||||
* Returns FALSE if nothing has stripped, TRUE if otherwise
|
* Returns FALSE if nothing has stripped, TRUE if otherwise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
gboolean
|
static gboolean
|
||||||
gst_metadata_parse_get_strip_range (gint64 * boffset, guint32 * bsize,
|
gst_metadata_parse_get_strip_range (gint64 * boffset, guint32 * bsize,
|
||||||
const gint64 seg_offset, const guint32 seg_size,
|
const gint64 seg_offset, const guint32 seg_size,
|
||||||
gint64 * toffset, guint32 * tsize, gint64 * ioffset)
|
gint64 * toffset, guint32 * tsize, gint64 * ioffset)
|
||||||
|
@ -1076,8 +1219,9 @@ done:
|
||||||
* FALSE -> buffer unmodified
|
* FALSE -> buffer unmodified
|
||||||
*/
|
*/
|
||||||
|
|
||||||
gboolean
|
static gboolean
|
||||||
gst_metadata_parse_strip_buffer (GstMetadataParse * filter, GstBuffer ** buf)
|
gst_metadata_parse_strip_buffer (GstMetadataParse * filter, gint64 offset,
|
||||||
|
GstBuffer ** buf)
|
||||||
{
|
{
|
||||||
|
|
||||||
gint64 boffset[3];
|
gint64 boffset[3];
|
||||||
|
@ -1095,7 +1239,6 @@ gst_metadata_parse_strip_buffer (GstMetadataParse * filter, GstBuffer ** buf)
|
||||||
int i;
|
int i;
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
guint32 new_size = 0;
|
guint32 new_size = 0;
|
||||||
const gint64 offset = filter->offset;
|
|
||||||
|
|
||||||
if (filter->num_segs == 0)
|
if (filter->num_segs == 0)
|
||||||
goto done;
|
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
|
static gboolean
|
||||||
gst_metadata_parse_get_range (GstPad * pad,
|
gst_metadata_parse_get_range (GstPad * pad,
|
||||||
guint64 offset, guint size, GstBuffer ** buf)
|
guint64 offset, guint size, GstBuffer ** buf)
|
||||||
{
|
{
|
||||||
GstMetadataParse *filter = NULL;
|
GstMetadataParse *filter = NULL;
|
||||||
|
gboolean ret;
|
||||||
|
gint64 pos;
|
||||||
|
const gint64 saved_offset = offset + size;
|
||||||
|
|
||||||
filter = GST_METADATA_PARSE (GST_PAD_PARENT (pad));
|
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);
|
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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,6 +96,7 @@ struct _GstMetadataParse
|
||||||
guint32 next_size;
|
guint32 next_size;
|
||||||
ImageType img_type;
|
ImageType img_type;
|
||||||
|
|
||||||
|
gint64 offset_orig;
|
||||||
gint64 duration;
|
gint64 duration;
|
||||||
gint64 offset;
|
gint64 offset;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue