static gboolean gst_speex_enc_src_query (GstPad * pad, GstQuery * query) { gboolean res = TRUE; GstSpeexEnc *enc; enc = GST_SPEEX_ENC (gst_pad_get_parent (pad)); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: { GstFormat fmt, req_fmt; gint64 pos, val; gst_query_parse_position (query, &req_fmt, NULL); if ((res = gst_pad_query_peer_position (enc->sinkpad, &req_fmt, &val))) { gst_query_set_position (query, req_fmt, val); break; } fmt = GST_FORMAT_TIME; if (!(res = gst_pad_query_peer_position (enc->sinkpad, &fmt, &pos))) break; if ((res = gst_pad_query_peer_convert (enc->sinkpad, fmt, pos, &req_fmt, &val))) gst_query_set_position (query, req_fmt, val); break; } case GST_QUERY_DURATION: { GstFormat fmt, req_fmt; gint64 dur, val; gst_query_parse_duration (query, &req_fmt, NULL); if ((res = gst_pad_query_peer_duration (enc->sinkpad, &req_fmt, &val))) { gst_query_set_duration (query, req_fmt, val); break; } fmt = GST_FORMAT_TIME; if (!(res = gst_pad_query_peer_duration (enc->sinkpad, &fmt, &dur))) break; if ((res = gst_pad_query_peer_convert (enc->sinkpad, fmt, dur, &req_fmt, &val))) { gst_query_set_duration (query, req_fmt, val); } break; } case GST_QUERY_CONVERT: { GstFormat src_fmt, dest_fmt; gint64 src_val, dest_val; gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val); if (!(res = gst_speex_enc_convert_src (pad, src_fmt, src_val, &dest_fmt, &dest_val))) goto error; gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val); break; } case GST_QUERY_LATENCY: { gboolean live; GstClockTime min_latency, max_latency; gint64 latency; if ((res = gst_pad_peer_query (enc->sinkpad, query))) { gst_query_parse_latency (query, &live, &min_latency, &max_latency); GST_LOG_OBJECT (pad, "Upstream latency: %" GST_PTR_FORMAT, query); latency = gst_speex_enc_get_latency (enc); /* add our latency */ min_latency += latency; if (max_latency != -1) max_latency += latency; gst_query_set_latency (query, live, min_latency, max_latency); GST_LOG_OBJECT (pad, "Adjusted latency: %" GST_PTR_FORMAT, query); } break; } default: res = gst_pad_peer_query (enc->sinkpad, query); break; } error: gst_object_unref (enc); return res; }
static gboolean speed_src_query (GstPad * pad, GstQuery * query) { gboolean ret = TRUE; GstSpeed *filter; filter = GST_SPEED (gst_pad_get_parent (pad)); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: { GstFormat format; GstFormat rformat = GST_FORMAT_TIME; gint64 cur; GstFormat conv_format = GST_FORMAT_TIME; /* save requested format */ gst_query_parse_position (query, &format, NULL); /* query peer for current position in time */ gst_query_set_position (query, GST_FORMAT_TIME, -1); if (!gst_pad_query_peer_position (filter->sinkpad, &rformat, &cur)) { GST_LOG_OBJECT (filter, "query on peer pad failed"); goto error; } if (rformat == GST_FORMAT_BYTES) GST_LOG_OBJECT (filter, "peer pad returned current=%" G_GINT64_FORMAT " bytes", cur); else if (rformat == GST_FORMAT_TIME) GST_LOG_OBJECT (filter, "peer pad returned time=%" G_GINT64_FORMAT, cur); /* convert to time format */ if (!gst_speed_convert (pad, rformat, cur, &conv_format, &cur)) { ret = FALSE; break; } /* adjust for speed factor */ cur /= filter->speed; /* convert to time format */ if (!gst_speed_convert (pad, conv_format, cur, &format, &cur)) { ret = FALSE; break; } gst_query_set_position (query, format, cur); GST_LOG_OBJECT (filter, "position query: we return %" G_GUINT64_FORMAT " (format %u)", cur, format); break; } case GST_QUERY_DURATION: { GstFormat format; GstFormat rformat = GST_FORMAT_TIME; gint64 end; GstFormat conv_format = GST_FORMAT_TIME; /* save requested format */ gst_query_parse_duration (query, &format, NULL); /* query peer for total length in time */ gst_query_set_duration (query, GST_FORMAT_TIME, -1); if (!gst_pad_query_peer_duration (filter->sinkpad, &rformat, &end)) { GST_LOG_OBJECT (filter, "query on peer pad failed"); goto error; } if (rformat == GST_FORMAT_BYTES) GST_LOG_OBJECT (filter, "peer pad returned total=%" G_GINT64_FORMAT " bytes", end); else if (rformat == GST_FORMAT_TIME) GST_LOG_OBJECT (filter, "peer pad returned time=%" G_GINT64_FORMAT, end); /* convert to time format */ if (!gst_speed_convert (pad, rformat, end, &conv_format, &end)) { ret = FALSE; break; } /* adjust for speed factor */ end /= filter->speed; /* convert to time format */ if (!gst_speed_convert (pad, conv_format, end, &format, &end)) { ret = FALSE; break; } gst_query_set_duration (query, format, end); GST_LOG_OBJECT (filter, "duration query: we return %" G_GUINT64_FORMAT " (format %u)", end, format); break; } default: ret = FALSE; break; } gst_object_unref (filter); return ret; error: gst_object_unref (filter); GST_DEBUG ("error handling query"); return FALSE; }
static gboolean gst_au_parse_src_query (GstPad * pad, GstQuery * query) { GstAuParse *auparse; gboolean ret = FALSE; auparse = GST_AU_PARSE (gst_pad_get_parent (pad)); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_DURATION:{ GstFormat bformat = GST_FORMAT_BYTES; GstFormat format; gint64 len, val; gst_query_parse_duration (query, &format, NULL); if (!gst_pad_query_peer_duration (auparse->sinkpad, &bformat, &len)) { GST_DEBUG_OBJECT (auparse, "failed to query upstream length"); break; } GST_OBJECT_LOCK (auparse); len -= auparse->offset; GST_OBJECT_UNLOCK (auparse); ret = gst_au_parse_src_convert (auparse, bformat, len, format, &val); if (ret) { gst_query_set_duration (query, format, val); } break; } case GST_QUERY_POSITION:{ GstFormat bformat = GST_FORMAT_BYTES; GstFormat format; gint64 pos, val; gst_query_parse_position (query, &format, NULL); if (!gst_pad_query_peer_position (auparse->sinkpad, &bformat, &pos)) { GST_DEBUG_OBJECT (auparse, "failed to query upstream position"); break; } GST_OBJECT_LOCK (auparse); pos -= auparse->offset; GST_OBJECT_UNLOCK (auparse); ret = gst_au_parse_src_convert (auparse, GST_FORMAT_BYTES, pos, format, &val); if (ret) { gst_query_set_position (query, format, val); } break; } case GST_QUERY_SEEKING:{ GstFormat format; gst_query_parse_seeking (query, &format, NULL, NULL, NULL); /* FIXME: query duration in 'format' gst_query_set_seeking (query, format, TRUE, 0, duration); */ gst_query_set_seeking (query, format, TRUE, 0, GST_CLOCK_TIME_NONE); ret = TRUE; break; } default: ret = gst_pad_query_default (pad, query); break; } gst_object_unref (auparse); return ret; }
static gboolean gst_live_adder_query_pos_dur (GstLiveAdder * adder, GstFormat informat, gboolean position, gint64 * outvalue) { gint64 max = G_MININT64; gboolean res = TRUE; GstIterator *it; gboolean done = FALSE; it = gst_element_iterate_sink_pads (GST_ELEMENT_CAST (adder)); while (!done) { GstIteratorResult ires; gpointer item; GstFormat format = informat; ires = gst_iterator_next (it, &item); switch (ires) { case GST_ITERATOR_DONE: done = TRUE; break; case GST_ITERATOR_OK: { GstPad *pad = GST_PAD_CAST (item); gint64 value; gboolean curres; /* ask sink peer for duration */ if (position) curres = gst_pad_query_peer_position (pad, &format, &value); else curres = gst_pad_query_peer_duration (pad, &format, &value); /* take max from all valid return values */ /* Only if the format is the one we requested, otherwise ignore it ? */ if (curres && format == informat) { res &= curres; /* valid unknown length, stop searching */ if (value == -1) { max = value; done = TRUE; } else if (value > max) { max = value; } } break; } case GST_ITERATOR_RESYNC: max = -1; res = TRUE; break; default: res = FALSE; done = TRUE; break; } } gst_iterator_free (it); if (res) *outvalue = max; return res; }