static gboolean gst_frei0r_mixer_src_query (GstPad * pad, GstObject * object, GstQuery * query) { GstFrei0rMixer *self = GST_FREI0R_MIXER (object); gboolean ret = FALSE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: ret = gst_pad_query (self->sink0, query); break; case GST_QUERY_DURATION: ret = gst_frei0r_mixer_src_query_duration (self, query); break; case GST_QUERY_LATENCY: ret = gst_frei0r_mixer_src_query_latency (self, query); break; case GST_QUERY_CAPS: { GstCaps *filter, *caps; gst_query_parse_caps (query, &filter); caps = gst_frei0r_mixer_get_caps (self, pad, filter); gst_query_set_caps_result (query, caps); gst_caps_unref (caps); break; } default: ret = gst_pad_query_default (pad, GST_OBJECT (self), query); break; } return ret; }
static gboolean gst_frei0r_mixer_src_query (GstPad * pad, GstQuery * query) { GstFrei0rMixer *self = GST_FREI0R_MIXER (gst_pad_get_parent (pad)); gboolean ret = FALSE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: ret = gst_pad_query (self->sink0, query); break; case GST_QUERY_DURATION: ret = gst_frei0r_mixer_src_query_duration (self, query); break; case GST_QUERY_LATENCY: ret = gst_frei0r_mixer_src_query_latency (self, query); break; default: ret = gst_pad_query_default (pad, query); break; } gst_object_unref (self); return ret; }
static gboolean splitmux_part_pad_query (GstPad * pad, GstObject * parent, GstQuery * query) { GstSplitMuxPartPad *part_pad = SPLITMUX_PART_PAD_CAST (pad); GstSplitMuxPartReader *reader = part_pad->reader; GstPad *target; gboolean ret = FALSE; gboolean active; SPLITMUX_PART_LOCK (reader); target = gst_object_ref (part_pad->target); active = reader->active; SPLITMUX_PART_UNLOCK (reader); if (active) { GST_LOG_OBJECT (pad, "Forwarding query %" GST_PTR_FORMAT " from %" GST_PTR_FORMAT " on %" GST_PTR_FORMAT, query, pad, target); ret = gst_pad_query (target, query); } gst_object_unref (target); return ret; }
static gboolean audioresample_query (GstPad * pad, GstQuery * query) { GstAudioresample *audioresample = GST_AUDIORESAMPLE (gst_pad_get_parent (pad)); GstBaseTransform *trans = GST_BASE_TRANSFORM (audioresample); gboolean res = TRUE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY: { GstClockTime min, max; gboolean live; guint64 latency; GstPad *peer; gint rate = audioresample->i_rate; gint resampler_latency = audioresample->filter_length / 2; if (gst_base_transform_is_passthrough (trans)) resampler_latency = 0; if ((peer = gst_pad_get_peer (trans->sinkpad))) { if ((res = gst_pad_query (peer, query))) { gst_query_parse_latency (query, &live, &min, &max); GST_DEBUG ("Peer latency: min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min), GST_TIME_ARGS (max)); /* add our own latency */ if (rate != 0 && resampler_latency != 0) latency = gst_util_uint64_scale (resampler_latency, GST_SECOND, rate); else latency = 0; GST_DEBUG ("Our latency: %" GST_TIME_FORMAT, GST_TIME_ARGS (latency)); min += latency; if (max != GST_CLOCK_TIME_NONE) max += latency; GST_DEBUG ("Calculated total latency : min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min), GST_TIME_ARGS (max)); gst_query_set_latency (query, live, min, max); } gst_object_unref (peer); } break; } default: res = gst_pad_query_default (pad, query); break; } gst_object_unref (audioresample); return res; }
static gboolean gst_y4m_dec_src_query (GstPad * pad, GstQuery * query) { GstY4mDec *y4mdec = GST_Y4M_DEC (gst_pad_get_parent (pad)); gboolean res = FALSE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_DURATION: { GstFormat format; GstPad *peer; GST_DEBUG ("duration query"); gst_query_parse_duration (query, &format, NULL); if (format != GST_FORMAT_TIME) { res = FALSE; GST_DEBUG_OBJECT (y4mdec, "not handling duration query in format %d", format); break; } peer = gst_pad_get_peer (y4mdec->sinkpad); if (peer) { GstQuery *peer_query = gst_query_new_duration (GST_FORMAT_BYTES); res = gst_pad_query (peer, peer_query); if (res) { gint64 duration; int n_frames; gst_query_parse_duration (peer_query, &format, &duration); n_frames = gst_y4m_dec_bytes_to_frames (y4mdec, duration); GST_DEBUG ("duration in frames %d", n_frames); duration = gst_y4m_dec_frames_to_timestamp (y4mdec, n_frames); GST_DEBUG ("duration in time %" GST_TIME_FORMAT, GST_TIME_ARGS (duration)); gst_query_set_duration (query, GST_FORMAT_TIME, duration); res = TRUE; } gst_query_unref (peer_query); gst_object_unref (peer); } break; } default: res = gst_pad_query_default (pad, query); break; } gst_object_unref (y4mdec); return res; }
static gboolean gst_audio_fx_base_fir_filter_query (GstPad * pad, GstQuery * query) { GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (gst_pad_get_parent (pad)); gboolean res = TRUE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY: { GstClockTime min, max; gboolean live; guint64 latency; GstPad *peer; gint rate = GST_AUDIO_FILTER (self)->format.rate; if (rate == 0) { res = FALSE; } else if ((peer = gst_pad_get_peer (GST_BASE_TRANSFORM (self)->sinkpad))) { if ((res = gst_pad_query (peer, query))) { gst_query_parse_latency (query, &live, &min, &max); GST_DEBUG_OBJECT (self, "Peer latency: min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min), GST_TIME_ARGS (max)); if (self->fft && !self->low_latency) latency = self->block_length - self->kernel_length + 1; else latency = self->latency; /* add our own latency */ latency = gst_util_uint64_scale_round (latency, GST_SECOND, rate); GST_DEBUG_OBJECT (self, "Our latency: %" GST_TIME_FORMAT, GST_TIME_ARGS (latency)); min += latency; if (max != GST_CLOCK_TIME_NONE) max += latency; GST_DEBUG_OBJECT (self, "Calculated total latency : min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min), GST_TIME_ARGS (max)); gst_query_set_latency (query, live, min, max); } gst_object_unref (peer); } break; } default: res = gst_pad_query_default (pad, query); break; } gst_object_unref (self); return res; }
static gboolean gst_base_video_encoder_src_query (GstPad * pad, GstQuery * query) { GstBaseVideoEncoder *enc; gboolean res; GstPad *peerpad; enc = GST_BASE_VIDEO_ENCODER (gst_pad_get_parent (pad)); peerpad = gst_pad_get_peer (GST_BASE_VIDEO_CODEC_SINK_PAD (enc)); switch GST_QUERY_TYPE (query) { 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); res = gst_base_video_encoded_video_convert (&GST_BASE_VIDEO_CODEC (enc)->state, src_fmt, src_val, &dest_fmt, &dest_val); if (!res) 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; res = gst_pad_query (peerpad, query); if (res) { gst_query_parse_latency (query, &live, &min_latency, &max_latency); min_latency += enc->min_latency; if (max_latency != GST_CLOCK_TIME_NONE) { max_latency += enc->max_latency; } gst_query_set_latency (query, live, min_latency, max_latency); } } break; default: res = gst_pad_query_default (pad, query); } gst_object_unref (peerpad); gst_object_unref (enc); return res; error: GST_DEBUG_OBJECT (enc, "query failed"); gst_object_unref (peerpad); gst_object_unref (enc); return res; }
static gboolean gst_schro_dec_src_query (GstPad *pad, GstQuery *query) { GstSchroDec *dec; gboolean res = FALSE; dec = GST_SCHRO_DEC (gst_pad_get_parent(pad)); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: { GstFormat format; gint64 time; gint64 value; gst_query_parse_position (query, &format, NULL); time = gst_util_uint64_scale (granulepos_to_frame (dec->granulepos), dec->fps_n, dec->fps_d); //time -= dec->segment.start; time += dec->segment.time; GST_DEBUG("query position %lld", time); res = gst_schro_dec_src_convert (pad, GST_FORMAT_TIME, time, &format, &value); if (!res) goto error; gst_query_set_position (query, format, value); break; } case GST_QUERY_DURATION: res = gst_pad_query (GST_PAD_PEER (dec->sinkpad), query); if (!res) goto error; 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); res = gst_schro_dec_src_convert (pad, src_fmt, src_val, &dest_fmt, &dest_val); if (!res) goto error; gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val); break; } default: res = gst_pad_query_default (pad, query); break; } done: gst_object_unref (dec); return res; error: GST_DEBUG_OBJECT (dec, "query failed"); goto done; }
static gboolean gst_frei0r_mixer_sink_query (GstPad * pad, GstQuery * query) { GstFrei0rMixer *self = GST_FREI0R_MIXER (gst_pad_get_parent (pad)); gboolean ret = gst_pad_query (self->src, query); gst_object_unref (self); return ret; }
static gboolean gst_proxy_pad_do_query (GstPad * pad, GstQuery * query) { gboolean res = FALSE; GstPad *target = gst_proxy_pad_get_target (pad); if (target) { res = gst_pad_query (target, query); gst_object_unref (target); } return res; }
static gboolean event_forward_func (GstPad * pad, EventData * evdata) { gboolean ret = TRUE; GstPad *peer = gst_pad_get_peer (pad); GstAggregatorPadPrivate *padpriv = GST_AGGREGATOR_PAD (pad)->priv; if (peer) { ret = gst_pad_send_event (peer, gst_event_ref (evdata->event)); GST_DEBUG_OBJECT (pad, "return of event push is %d", ret); gst_object_unref (peer); } if (ret == FALSE) { if (GST_EVENT_TYPE (evdata->event) == GST_EVENT_SEEK) GST_ERROR_OBJECT (pad, "Event %" GST_PTR_FORMAT " failed", evdata->event); if (GST_EVENT_TYPE (evdata->event) == GST_EVENT_SEEK) { GstQuery *seeking = gst_query_new_seeking (GST_FORMAT_TIME); if (gst_pad_query (peer, seeking)) { gboolean seekable; gst_query_parse_seeking (seeking, NULL, &seekable, NULL, NULL); if (seekable == FALSE) { GST_INFO_OBJECT (pad, "Source not seekable, We failed but it does not matter!"); ret = TRUE; } } else { GST_ERROR_OBJECT (pad, "Query seeking FAILED"); } } if (evdata->flush) { padpriv->pending_flush_start = FALSE; padpriv->pending_flush_stop = FALSE; } } else { evdata->one_actually_seeked = TRUE; } evdata->result &= ret; /* Always send to all pads */ return FALSE; }
static gboolean gst_type_find_handle_src_query (GstPad * pad, GstQuery * query) { GstTypeFindElement *typefind; gboolean res = FALSE; GstPad *peer; typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad)); peer = gst_pad_get_peer (typefind->sink); if (peer == NULL) return FALSE; res = gst_pad_query (peer, query); if (!res) goto out; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: { gint64 peer_pos; GstFormat format; if (typefind->store == NULL) goto out; gst_query_parse_position (query, &format, &peer_pos); /* FIXME: this code assumes that there's no discont in the queue */ switch (format) { case GST_FORMAT_BYTES: peer_pos -= GST_BUFFER_SIZE (typefind->store); break; default: /* FIXME */ break; } gst_query_set_position (query, format, peer_pos); break; } default: break; } out: gst_object_unref (peer); return res; }
static gboolean gst_base_video_decoder_src_query (GstPad * pad, GstQuery * query) { GstBaseVideoDecoder *dec; gboolean res = TRUE; dec = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); switch GST_QUERY_TYPE (query) { case GST_QUERY_POSITION: { GstFormat format; gint64 time; gst_query_parse_position (query, &format, NULL); GST_DEBUG ("query in format %d", format); if (format != GST_FORMAT_TIME) { goto error; } time = dec->last_timestamp; time = gst_segment_to_stream_time (&dec->segment, GST_FORMAT_TIME, time); gst_query_set_position (query, format, time); res = TRUE; break; } case GST_QUERY_DURATION: /* FIXME: approximate using bitrate if upstream doesn't answear */ res = gst_pad_query (dec->sinkpad, query); break; default: res = gst_pad_query_default (pad, query); } gst_object_unref (dec); return res; error: GST_ERROR_OBJECT (dec, "query failed"); gst_object_unref (dec); return res; }
static gboolean gst_shape_wipe_src_query (GstPad * pad, GstQuery * query) { GstShapeWipe *self = GST_SHAPE_WIPE (gst_pad_get_parent (pad)); gboolean ret; GstPad *peer = gst_pad_get_peer (self->video_sinkpad); GST_DEBUG_OBJECT (pad, "Handling query of type '%s'", gst_query_type_get_name (GST_QUERY_TYPE (query))); if (!peer) { GST_INFO_OBJECT (pad, "No peer yet"); ret = FALSE; } else { ret = gst_pad_query (peer, query); gst_object_unref (peer); } gst_object_unref (self); return ret; }
static gboolean gst_webrtc_echo_probe_src_event (GstBaseTransform * btrans, GstEvent * event) { GstBaseTransformClass *klass; GstWebrtcEchoProbe *self = GST_WEBRTC_ECHO_PROBE (btrans); GstClockTime latency; GstClockTime upstream_latency = 0; GstQuery *query; klass = GST_BASE_TRANSFORM_CLASS (gst_webrtc_echo_probe_parent_class); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_LATENCY: gst_event_parse_latency (event, &latency); query = gst_query_new_latency (); if (gst_pad_query (btrans->srcpad, query)) { gst_query_parse_latency (query, NULL, &upstream_latency, NULL); if (!GST_CLOCK_TIME_IS_VALID (upstream_latency)) upstream_latency = 0; } GST_WEBRTC_ECHO_PROBE_LOCK (self); self->latency = latency; self->delay = upstream_latency / GST_MSECOND; GST_WEBRTC_ECHO_PROBE_UNLOCK (self); GST_DEBUG_OBJECT (self, "We have a latency of %" GST_TIME_FORMAT " and delay of %ims", GST_TIME_ARGS (latency), (gint) (upstream_latency / GST_MSECOND)); break; default: break; } return klass->src_event (btrans, event); }
static gboolean theora_parse_src_query (GstPad * pad, GstObject * parent, GstQuery * query) { GstTheoraParse *parse; gboolean res = FALSE; parse = GST_THEORA_PARSE (parent); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: { gint64 frame, value; GstFormat my_format, format; gint64 time; frame = parse->prev_frame; GST_LOG_OBJECT (parse, "query %p: we have current frame: %" G_GINT64_FORMAT, query, frame); /* parse format */ gst_query_parse_position (query, &format, NULL); /* and convert to the final format in two steps with time as the * intermediate step */ my_format = GST_FORMAT_TIME; if (!(res = theora_parse_src_convert (parse->sinkpad, GST_FORMAT_DEFAULT, frame, &my_format, &time))) goto error; /* fixme: handle segments time = (time - parse->segment.start) + parse->segment.time; */ GST_LOG_OBJECT (parse, "query %p: our time: %" GST_TIME_FORMAT " (conv to %s)", query, GST_TIME_ARGS (time), gst_format_get_name (format)); if (!(res = theora_parse_src_convert (pad, my_format, time, &format, &value))) goto error; gst_query_set_position (query, format, value); GST_LOG_OBJECT (parse, "query %p: we return %" G_GINT64_FORMAT " (format %u)", query, value, format); break; } case GST_QUERY_DURATION: /* forward to peer for total */ if (!(res = gst_pad_query (GST_PAD_PEER (parse->sinkpad), query))) goto error; 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 = theora_parse_src_convert (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; } default: res = gst_pad_query_default (pad, parent, query); break; } done: return res; /* ERRORS */ error: { GST_DEBUG_OBJECT (parse, "query failed"); goto done; } }
void test_queries() { GstBin *bin; GstElement *src, *sink; GstStateChangeReturn ret; GstPad *pad; GstQuery *dur, *pos; xmlfile = "gstquery_test_queries"; std_log(LOG_FILENAME_LINE, "Test Started test_queries"); fail_unless ((bin = (GstBin *) gst_pipeline_new (NULL)) != NULL, "Could not create pipeline"); fail_unless ((src = gst_element_factory_make ("fakesrc", NULL)) != NULL, "Could not create fakesrc"); g_object_set (src, "datarate", 200, "sizetype", 2, NULL); fail_unless ((sink = gst_element_factory_make ("fakesink", NULL)) != NULL, "Could not create fakesink"); g_object_set (sink, "sync", TRUE, NULL); fail_unless ((dur = gst_query_new_duration (GST_FORMAT_BYTES)) != NULL, "Could not prepare duration query"); fail_unless ((pos = gst_query_new_position (GST_FORMAT_BYTES)) != NULL, "Could not prepare position query"); fail_unless (gst_bin_add (bin, src), "Could not add src to bin"); fail_unless (gst_bin_add (bin, sink), "Could not add sink to bin"); fail_unless (gst_element_link (src, sink), "could not link src and sink"); ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING); fail_if (ret == GST_STATE_CHANGE_FAILURE, "Failed to set pipeline PLAYING"); if (ret == GST_STATE_CHANGE_ASYNC) gst_element_get_state (GST_ELEMENT (bin), NULL, NULL, GST_CLOCK_TIME_NONE); /* Query the bin */ fail_unless (gst_element_query (GST_ELEMENT (bin), pos), "Could not query pipeline position"); fail_unless (gst_element_query (GST_ELEMENT (bin), dur), "Could not query pipeline duration"); /* Query elements */ fail_unless (gst_element_query (GST_ELEMENT (src), pos), "Could not query position of fakesrc"); fail_unless (gst_element_query (GST_ELEMENT (src), pos), "Could not query duration of fakesrc"); fail_unless (gst_element_query (GST_ELEMENT (sink), pos), "Could not query position of fakesink"); fail_unless (gst_element_query (GST_ELEMENT (sink), pos), "Could not query duration of fakesink"); /* Query pads */ fail_unless ((pad = gst_element_get_pad (src, "src")) != NULL, "Could not get source pad of fakesrc"); fail_unless (gst_pad_query (pad, pos), "Could not query position of fakesrc src pad"); fail_unless (gst_pad_query (pad, dur), "Could not query duration of fakesrc src pad"); gst_object_unref (pad); /* We don't query the sink pad of fakesink, it doesn't * handle downstream queries atm, but it might later, who knows? */ ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL); fail_if (ret == GST_STATE_CHANGE_FAILURE, "Failed to set pipeline NULL"); if (ret == GST_STATE_CHANGE_ASYNC) gst_element_get_state (GST_ELEMENT (bin), NULL, NULL, GST_CLOCK_TIME_NONE); gst_query_unref (dur); gst_query_unref (pos); gst_object_unref (bin); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
static gboolean vorbis_parse_src_query (GstPad * pad, GstQuery * query) { gint64 granulepos; GstVorbisParse *parse; gboolean res = FALSE; parse = GST_VORBIS_PARSE (GST_PAD_PARENT (pad)); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: { GstFormat format; gint64 value; granulepos = parse->prev_granulepos; gst_query_parse_position (query, &format, NULL); /* and convert to the final format */ if (!(res = vorbis_parse_convert (pad, GST_FORMAT_DEFAULT, granulepos, &format, &value))) goto error; /* fixme: support segments value = (value - parse->segment_start) + parse->segment_time; */ gst_query_set_position (query, format, value); GST_LOG_OBJECT (parse, "query %p: peer returned granulepos: %" G_GUINT64_FORMAT " - we return %" G_GUINT64_FORMAT " (format %u)", query, granulepos, value, format); break; } case GST_QUERY_DURATION: { /* fixme: not threadsafe */ /* query peer for total length */ if (!gst_pad_is_linked (parse->sinkpad)) { GST_WARNING_OBJECT (parse, "sink pad %" GST_PTR_FORMAT " is not linked", parse->sinkpad); goto error; } if (!(res = gst_pad_query (GST_PAD_PEER (parse->sinkpad), query))) goto error; 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 = vorbis_parse_convert (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; } default: res = gst_pad_query_default (pad, query); break; } return res; error: { GST_WARNING_OBJECT (parse, "error handling query"); return res; } }
static gboolean gst_video_rate_query (GstBaseTransform * trans, GstPadDirection direction, GstQuery * query) { GstVideoRate *videorate = GST_VIDEO_RATE (trans); gboolean res = FALSE; GstPad *otherpad; otherpad = (direction == GST_PAD_SRC) ? GST_BASE_TRANSFORM_SINK_PAD (trans) : GST_BASE_TRANSFORM_SRC_PAD (trans); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY: { GstClockTime min, max; gboolean live; guint64 latency; guint64 avg_period; GstPad *peer; GST_OBJECT_LOCK (videorate); avg_period = videorate->average_period_set; GST_OBJECT_UNLOCK (videorate); if (avg_period == 0 && (peer = gst_pad_get_peer (otherpad))) { if ((res = gst_pad_query (peer, query))) { gst_query_parse_latency (query, &live, &min, &max); GST_DEBUG_OBJECT (videorate, "Peer latency: min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min), GST_TIME_ARGS (max)); if (videorate->from_rate_numerator != 0) { /* add latency. We don't really know since we hold on to the frames * until we get a next frame, which can be anything. We assume * however that this will take from_rate time. */ latency = gst_util_uint64_scale (GST_SECOND, videorate->from_rate_denominator, videorate->from_rate_numerator); } else { /* no input framerate, we don't know */ latency = 0; } GST_DEBUG_OBJECT (videorate, "Our latency: %" GST_TIME_FORMAT, GST_TIME_ARGS (latency)); min += latency; if (max != -1) max += latency; GST_DEBUG_OBJECT (videorate, "Calculated total latency : min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min), GST_TIME_ARGS (max)); gst_query_set_latency (query, live, min, max); } gst_object_unref (peer); break; } /* Simple fallthrough if we don't have a latency or not a peer that we * can't ask about its latency yet.. */ } default: res = GST_BASE_TRANSFORM_CLASS (parent_class)->query (trans, direction, query); break; } return res; }
static gboolean mpegts_demuxer_src_query (GstPad *pad, GstObject *parent, GstQuery *query) { MpegTSDemuxer *demuxer = MPEGTS_DEMUXER(parent); return gst_pad_query(demuxer->sinkpad, query); }
bool Pad::query(const QueryPtr & query) { return gst_pad_query(object<GstPad>(), query); }
static gboolean theora_dec_src_query (GstPad * pad, GstQuery * query) { GstTheoraDec *dec; gboolean res = FALSE; dec = GST_THEORA_DEC (gst_pad_get_parent (pad)); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: { gint64 granulepos, value; GstFormat my_format, format; gint64 time; /* we can convert a granule position to everything */ granulepos = dec->granulepos; GST_LOG_OBJECT (dec, "query %p: we have current granule: %lld", query, granulepos); /* parse format */ gst_query_parse_position (query, &format, NULL); /* and convert to the final format in two steps with time as the * intermediate step */ my_format = GST_FORMAT_TIME; if (!(res = theora_dec_sink_convert (dec->sinkpad, GST_FORMAT_DEFAULT, granulepos, &my_format, &time))) goto error; time = gst_segment_to_stream_time (&dec->segment, GST_FORMAT_TIME, time); GST_LOG_OBJECT (dec, "query %p: our time: %" GST_TIME_FORMAT, query, GST_TIME_ARGS (time)); if (!(res = theora_dec_src_convert (pad, my_format, time, &format, &value))) goto error; gst_query_set_position (query, format, value); GST_LOG_OBJECT (dec, "query %p: we return %lld (format %u)", query, value, format); break; } case GST_QUERY_DURATION: { GstPad *peer; if (!(peer = gst_pad_get_peer (dec->sinkpad))) goto error; /* forward to peer for total */ res = gst_pad_query (peer, query); gst_object_unref (peer); if (!res) goto error; 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 = theora_dec_src_convert (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; } default: res = gst_pad_query_default (pad, query); break; } done: gst_object_unref (dec); return res; /* ERRORS */ error: { GST_DEBUG_OBJECT (dec, "query failed"); goto done; } }
gint main (gint argc, gchar * argv[]) { GstElement *pipeline, *filesrc, *decodebin; GstStateChangeReturn res; GstIterator *it; GstBus *bus; GValue data = { 0, }; gst_init (&argc, &argv); pipeline = gst_pipeline_new ("pipeline"); filesrc = gst_element_factory_make ("filesrc", "filesrc"); g_assert (filesrc); decodebin = gst_element_factory_make ("decodebin", "decodebin"); g_assert (decodebin); gst_bin_add_many (GST_BIN (pipeline), filesrc, decodebin, NULL); gst_element_link (filesrc, decodebin); if (argc < 2) { g_print ("usage: %s <filenames>\n", argv[0]); exit (-1); } if (!g_str_has_prefix (argv[1], "file://")) { g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL); } else { g_object_set (G_OBJECT (filesrc), "location", argv[1] + 7, NULL); } /* we've got to connect fakesinks to newly decoded pads to make sure * buffers have actually been flowing over those pads and caps have * been set on them. decodebin might insert internal queues and * without fakesinks it's pot-luck what caps we get from the pad, because * it depends on whether the queues have started pushing buffers yet or not. * With fakesinks we make sure that the pipeline doesn't go to PAUSED state * before each fakesink has a buffer queued. */ g_signal_connect (decodebin, "new-decoded-pad", G_CALLBACK (new_decoded_pad_cb), pipeline); bus = gst_element_get_bus (pipeline); g_print ("pause..\n"); res = gst_element_set_state (pipeline, GST_STATE_PAUSED); if (res == GST_STATE_CHANGE_FAILURE) { show_error ("Could not go to PAUSED state", bus); exit (-1); } g_print ("waiting..\n"); res = gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); if (res != GST_STATE_CHANGE_SUCCESS) { show_error ("Failed to complete state change to PAUSED", bus); exit (-1); } g_print ("stats..\n"); it = gst_element_iterate_src_pads (decodebin); while (gst_iterator_next (it, &data) == GST_ITERATOR_OK) { GstPad *pad = g_value_get_object (&data); GstCaps *caps; gchar *str; GstQuery *query; g_print ("stream %s:\n", GST_OBJECT_NAME (pad)); caps = gst_pad_query_caps (pad, NULL); str = gst_caps_to_string (caps); g_print (" caps: %s\n", str); g_free (str); gst_caps_unref (caps); query = gst_query_new_duration (GST_FORMAT_TIME); if (gst_pad_query (pad, query)) { gint64 duration; gst_query_parse_duration (query, NULL, &duration); g_print (" duration: %" GST_TIME_FORMAT "\n", GST_TIME_ARGS (duration)); } gst_query_unref (query); g_value_reset (&data); } g_value_unset (&data); gst_iterator_free (it); return 0; }
static gboolean gst_deinterlace2_src_query (GstPad * pad, GstQuery * query) { GstDeinterlace2 *self = GST_DEINTERLACE2 (gst_pad_get_parent (pad)); gboolean res = FALSE; GST_LOG_OBJECT (self, "%s query", GST_QUERY_TYPE_NAME (query)); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY: { GstClockTime min, max; gboolean live; GstPad *peer; if ((peer = gst_pad_get_peer (self->sinkpad))) { if ((res = gst_pad_query (peer, query))) { GstClockTime latency; gint fields_required = 0; gint method_latency = 0; if (self->method) { fields_required = gst_deinterlace_method_get_fields_required (self->method); method_latency = gst_deinterlace_method_get_latency (self->method); } gst_query_parse_latency (query, &live, &min, &max); GST_DEBUG ("Peer latency: min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min), GST_TIME_ARGS (max)); /* add our own latency */ latency = (fields_required + method_latency) * self->field_duration; GST_DEBUG ("Our latency: min %" GST_TIME_FORMAT ", max %" GST_TIME_FORMAT, GST_TIME_ARGS (latency), GST_TIME_ARGS (latency)); min += latency; if (max != GST_CLOCK_TIME_NONE) max += latency; else max = latency; GST_DEBUG ("Calculated total latency : min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min), GST_TIME_ARGS (max)); gst_query_set_latency (query, live, min, max); } gst_object_unref (peer); } break; } default: res = gst_pad_query_default (pad, query); break; } gst_object_unref (self); return res; }
gint main (gint argc, gchar * argv[]) { GstElement *pipeline; GError *error = NULL; gchar *description; GstElement *encoder, *decoder; GstPad *dec_sink, *enc_src; gst_init (&argc, &argv); if (argc < 3) { g_print ("usage: %s <inputfile> <outputfile>\n", argv[0]); return -1; } description = g_strdup_printf ("filesrc location=\"%s\" ! mad name=decoder ! " "vorbisenc name=encoder ! filesink location=\"%s\"", argv[1], argv[2]); pipeline = GST_ELEMENT (gst_parse_launch (description, &error)); if (!pipeline) { if (error) g_print ("ERROR: pipeline could not be constructed: %s\n", error->message); else g_print ("ERROR: pipeline could not be constructed\n"); return -1; } decoder = gst_bin_get_by_name (GST_BIN (pipeline), "decoder"); encoder = gst_bin_get_by_name (GST_BIN (pipeline), "encoder"); dec_sink = gst_element_get_pad (decoder, "sink"); enc_src = gst_element_get_pad (encoder, "src"); if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_CHANGE_SUCCESS) { g_print ("pipeline doesn't want to play\n"); return -1; } while (gst_bin_iterate (GST_BIN (pipeline))) { gint64 position; gint64 duration; gint64 bitrate_enc, bitrate_dec; GstFormat format; format = GST_FORMAT_TIME; /* get the position */ gst_pad_query (enc_src, GST_QUERY_POSITION, &format, &position); /* get the total duration */ gst_pad_query (enc_src, GST_QUERY_TOTAL, &format, &duration); format = GST_FORMAT_BYTES; /* see how many bytes are genereated per 8 seconds (== bitrate) */ gst_pad_convert (enc_src, GST_FORMAT_TIME, 8 * GST_SECOND, &format, &bitrate_enc); gst_pad_convert (dec_sink, GST_FORMAT_TIME, 8 * GST_SECOND, &format, &bitrate_dec); g_print ("[%2dm %.2ds] of [%2dm %.2ds], " "src avg bitrate: %" G_GINT64_FORMAT ", dest avg birate: %" G_GINT64_FORMAT ", ratio [%02.2f] \r", (gint) (position / (GST_SECOND * 60)), (gint) (position / (GST_SECOND)) % 60, (gint) (duration / (GST_SECOND * 60)), (gint) (duration / (GST_SECOND)) % 60, bitrate_dec, bitrate_enc, (gfloat) bitrate_dec / bitrate_enc); } g_print ("\n"); return 0; }
static gboolean gst_base_video_codec_src_query (GstPad * pad, GstQuery * query) { GstBaseVideoCodec *base_codec; gboolean res = FALSE; base_codec = GST_BASE_VIDEO_CODEC (gst_pad_get_parent (pad)); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: { GstFormat format; gint64 time; gint64 value; gst_query_parse_position (query, &format, NULL); time = gst_util_uint64_scale (base_codec->system_frame_number, base_codec->state.fps_n, base_codec->state.fps_d); time += base_codec->state.segment.time; GST_DEBUG ("query position %" GST_TIME_FORMAT, GST_TIME_ARGS (time)); res = gst_base_video_encoded_video_convert (&base_codec->state, GST_FORMAT_TIME, time, &format, &value); if (!res) goto error; gst_query_set_position (query, format, value); break; } case GST_QUERY_DURATION: res = gst_pad_query (GST_PAD_PEER (base_codec->sinkpad), query); if (!res) goto error; break; case GST_QUERY_CONVERT: { GstFormat src_fmt, dest_fmt; gint64 src_val, dest_val; GST_DEBUG ("query convert"); gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val); res = gst_base_video_encoded_video_convert (&base_codec->state, src_fmt, src_val, &dest_fmt, &dest_val); if (!res) goto error; gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val); break; } default: res = gst_pad_query_default (pad, query); break; } done: gst_object_unref (base_codec); return res; error: GST_DEBUG_OBJECT (base_codec, "query failed"); goto done; }
static gboolean gst_video_rate_query (GstPad * pad, GstQuery * query) { GstVideoRate *videorate; gboolean res = FALSE; videorate = GST_VIDEO_RATE (gst_pad_get_parent (pad)); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY: { GstClockTime min, max; gboolean live; guint64 latency; GstPad *peer; if ((peer = gst_pad_get_peer (videorate->sinkpad))) { if ((res = gst_pad_query (peer, query))) { gst_query_parse_latency (query, &live, &min, &max); GST_DEBUG_OBJECT (videorate, "Peer latency: min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min), GST_TIME_ARGS (max)); if (videorate->from_rate_numerator != 0) { /* add latency. We don't really know since we hold on to the frames * until we get a next frame, which can be anything. We assume * however that this will take from_rate time. */ latency = gst_util_uint64_scale (GST_SECOND, videorate->from_rate_denominator, videorate->from_rate_numerator); } else { /* no input framerate, we don't know */ latency = 0; } GST_DEBUG_OBJECT (videorate, "Our latency: %" GST_TIME_FORMAT, GST_TIME_ARGS (latency)); min += latency; if (max != -1) max += latency; GST_DEBUG_OBJECT (videorate, "Calculated total latency : min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min), GST_TIME_ARGS (max)); gst_query_set_latency (query, live, min, max); } gst_object_unref (peer); } break; } default: res = gst_pad_query_default (pad, query); break; } gst_object_unref (videorate); return res; }