diff options
Diffstat (limited to 'gst/speed/gstspeed.c')
-rw-r--r-- | gst/speed/gstspeed.c | 85 |
1 files changed, 82 insertions, 3 deletions
diff --git a/gst/speed/gstspeed.c b/gst/speed/gstspeed.c index 79b39f85..f784c105 100644 --- a/gst/speed/gstspeed.c +++ b/gst/speed/gstspeed.c @@ -169,6 +169,80 @@ gst_speed_get_type (void) return speed_type; } +static const GstQueryType * +speed_get_query_types (GstPad * pad) +{ + static const GstQueryType src_query_types[] = { + GST_QUERY_TOTAL, + GST_QUERY_POSITION, + 0 + }; + + return src_query_types; +} + +static gboolean +speed_src_query (GstPad * pad, GstQueryType type, + GstFormat * format, gint64 * val) +{ + gboolean res = TRUE; + GstSpeed *filter; + + filter = GST_SPEED (gst_pad_get_parent (pad)); + + switch (type) { + case GST_QUERY_POSITION: + case GST_QUERY_TOTAL: + { + switch (*format) { + case GST_FORMAT_BYTES: + case GST_FORMAT_DEFAULT: + case GST_FORMAT_TIME: + { + gint64 peer_value; + const GstFormat *peer_formats; + + res = FALSE; + + peer_formats = gst_pad_get_formats (GST_PAD_PEER (filter->sinkpad)); + + while (peer_formats && *peer_formats && !res) { + + GstFormat peer_format = *peer_formats; + + /* do the probe */ + if (gst_pad_query (GST_PAD_PEER (filter->sinkpad), type, + &peer_format, &peer_value)) { + GstFormat conv_format; + + /* convert to TIME */ + conv_format = GST_FORMAT_TIME; + res = gst_pad_convert (filter->sinkpad, + peer_format, peer_value, &conv_format, val); + + /* adjust for speed factor */ + *val = (gint64) (((gdouble) * val) / filter->speed); + + /* and to final format */ + res &= gst_pad_convert (pad, GST_FORMAT_TIME, *val, format, val); + } + peer_formats++; + } + break; + } + default: + res = FALSE; + break; + } + break; + } + default: + res = FALSE; + break; + } + return res; +} + static void speed_base_init (gpointer g_class) { @@ -214,6 +288,8 @@ speed_init (GstSpeed * filter) (&gst_speed_src_template), "src"); gst_pad_set_link_function (filter->srcpad, speed_link); gst_pad_set_getcaps_function (filter->srcpad, gst_pad_proxy_getcaps); + gst_pad_set_query_type_function (filter->srcpad, speed_get_query_types); + gst_pad_set_query_function (filter->srcpad, speed_src_query); gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad); filter->offset = 0; @@ -307,12 +383,15 @@ speed_chain (GstPad * pad, GstData * data) { gint64 timestamp, offset; + if (gst_event_discont_get_value (GST_EVENT (data), GST_FORMAT_TIME, + ×tamp)) { + filter->timestamp = timestamp; + filter->offset = timestamp * filter->rate / GST_SECOND; + } if (gst_event_discont_get_value (GST_EVENT (data), GST_FORMAT_BYTES, - ×tamp) - && gst_event_discont_get_value (GST_EVENT (data), GST_FORMAT_BYTES, &offset)) { filter->offset = offset; - filter->timestamp = timestamp; + filter->timestamp = offset * GST_SECOND / filter->rate; } break; } |