static gboolean gst_deinterleave_src_query (GstPad * pad, GstQuery * query) { GstDeinterleave *self = GST_DEINTERLEAVE (gst_pad_get_parent (pad)); gboolean res; res = gst_pad_query_default (pad, query); if (res && GST_QUERY_TYPE (query) == GST_QUERY_DURATION) { GstFormat format; gint64 dur; gst_query_parse_duration (query, &format, &dur); /* Need to divide by the number of channels in byte format * to get the correct value. All other formats should be fine */ if (format == GST_FORMAT_BYTES && dur != -1) gst_query_set_duration (query, format, dur / self->channels); } else if (res && GST_QUERY_TYPE (query) == GST_QUERY_POSITION) { GstFormat format; gint64 pos; gst_query_parse_position (query, &format, &pos); /* Need to divide by the number of channels in byte format * to get the correct value. All other formats should be fine */ if (format == GST_FORMAT_BYTES && pos != -1) gst_query_set_position (query, format, pos / self->channels); } gst_object_unref (self); return res; }
static gboolean gst_vdp_mpeg_dec_src_query (GstPad * pad, GstQuery * query) { GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (gst_pad_get_parent (pad)); gboolean res; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: { GstFormat format; if ((res = gst_pad_query_default (pad, query))) goto done; gst_query_parse_position (query, &format, NULL); if (format == GST_FORMAT_TIME && GST_CLOCK_TIME_IS_VALID (mpeg_dec->next_timestamp)) { gst_query_set_position (query, GST_FORMAT_TIME, mpeg_dec->next_timestamp); res = TRUE; } break; } case GST_QUERY_DURATION: { GstFormat format; if ((res = gst_pad_query_default (pad, query))) goto done; gst_query_parse_duration (query, &format, NULL); if (format == GST_FORMAT_TIME) { gint64 bytes; format = GST_FORMAT_BYTES; if (gst_pad_query_duration (pad, &format, &bytes) && format == GST_FORMAT_BYTES) { gint64 duration; if (gst_vdp_mpeg_dec_convert (mpeg_dec, GST_FORMAT_BYTES, bytes, GST_FORMAT_TIME, &duration)) { GST_DEBUG ("duration: %" GST_TIME_FORMAT, GST_TIME_ARGS (duration)); gst_query_set_duration (query, GST_FORMAT_TIME, duration); res = TRUE; } } } break; } default: res = gst_pad_query_default (pad, query); } done: gst_object_unref (mpeg_dec); return res; }
static gboolean gst_avdtp_src_query (GstBaseSrc * bsrc, GstQuery * query) { GstAvdtpSrc *avdtpsrc = GST_AVDTP_SRC (bsrc); gboolean ret = FALSE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_DURATION:{ GstFormat format; if (avdtpsrc->duration != GST_CLOCK_TIME_NONE) { gst_query_parse_duration (query, &format, NULL); if (format == GST_FORMAT_TIME) { gst_query_set_duration (query, format, (gint64) avdtpsrc->duration); ret = TRUE; } } break; } default: ret = GST_BASE_SRC_CLASS (parent_class)->query (bsrc, query); } return ret; }
static gboolean gst_midi_parse_src_query (GstPad * pad, GstObject * parent, GstQuery * query) { gboolean res = TRUE; GstMidiParse *midiparse = GST_MIDI_PARSE (parent); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_DURATION: gst_query_set_duration (query, GST_FORMAT_TIME, midiparse->segment.duration); break; case GST_QUERY_POSITION: gst_query_set_position (query, GST_FORMAT_TIME, midiparse->segment.position); break; case GST_QUERY_FORMATS: gst_query_set_formats (query, 1, GST_FORMAT_TIME); break; case GST_QUERY_SEGMENT: gst_query_set_segment (query, midiparse->segment.rate, midiparse->segment.format, midiparse->segment.start, midiparse->segment.stop); break; case GST_QUERY_SEEKING: gst_query_set_seeking (query, midiparse->segment.format, FALSE, 0, midiparse->segment.duration); break; default: res = gst_pad_query_default (pad, parent, query); break; } return res; }
static gboolean gst_flxdec_src_query_handler (GstPad * pad, GstObject * parent, GstQuery * query) { GstFlxDec *flxdec = (GstFlxDec *) parent; gboolean ret = FALSE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_DURATION: { GstFormat format; gst_query_parse_duration (query, &format, NULL); if (format != GST_FORMAT_TIME) goto done; gst_query_set_duration (query, format, flxdec->duration); ret = TRUE; } default: break; } done: if (!ret) ret = gst_pad_query_default (pad, parent, query); return ret; }
static gboolean gst_hls_demux_src_query (GstPad * pad, GstQuery * query) { GstHLSDemux *hlsdemux; gboolean ret = FALSE; if (query == NULL) return FALSE; hlsdemux = GST_HLS_DEMUX (gst_pad_get_element_private (pad)); switch (query->type) { case GST_QUERY_DURATION:{ GstClockTime duration; GstFormat fmt; gst_query_parse_duration (query, &fmt, NULL); if (fmt == GST_FORMAT_TIME) { duration = gst_m3u8_client_get_duration (hlsdemux->client); if (GST_CLOCK_TIME_IS_VALID (duration) && duration > 0) { gst_query_set_duration (query, GST_FORMAT_TIME, duration); ret = TRUE; } } break; } case GST_QUERY_URI: if (hlsdemux->client) { /* FIXME: Do we answer with the variant playlist, with the current * playlist or the the uri of the least downlowaded fragment? */ gst_query_set_uri (query, hlsdemux->client->current->uri); ret = TRUE; } break; case GST_QUERY_SEEKING:{ GstFormat fmt; gint stop = -1; gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL); if (fmt == GST_FORMAT_TIME) { GstClockTime duration; duration = gst_m3u8_client_get_duration (hlsdemux->client); if (GST_CLOCK_TIME_IS_VALID (duration) && duration > 0) stop = duration; } gst_query_set_seeking (query, fmt, FALSE, 0, stop); ret = TRUE; break; } default: /* Don't fordward queries upstream because of the special nature of this * "demuxer", which relies on the upstream element only to be fed with the * first playlist */ break; } return ret; }
/* FIXME operating in TIME rather than BYTES could remove this altogether * and be more convenient elsewhere */ static gboolean gst_mms_query (GstBaseSrc * src, GstQuery * query) { GstMMS *mmssrc = GST_MMS (src); gboolean res = TRUE; GstFormat format; gint64 value; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: gst_query_parse_position (query, &format, &value); if (format != GST_FORMAT_BYTES) { res = FALSE; break; } value = (gint64) mmsx_get_current_pos (mmssrc->connection); gst_query_set_position (query, format, value); break; case GST_QUERY_DURATION: if (!mmsx_get_seekable (mmssrc->connection)) { res = FALSE; break; } gst_query_parse_duration (query, &format, &value); switch (format) { case GST_FORMAT_BYTES: value = (gint64) mmsx_get_length (mmssrc->connection); gst_query_set_duration (query, format, value); break; case GST_FORMAT_TIME: value = mmsx_get_time_length (mmssrc->connection) * GST_SECOND; gst_query_set_duration (query, format, value); break; default: res = FALSE; } break; default: /* chain to parent */ res = GST_BASE_SRC_CLASS (parent_class)->query (GST_BASE_SRC (src), query); break; } 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_rtmp_src_query (GstBaseSrc * basesrc, GstQuery * query) { gboolean ret = FALSE; GstRTMPSrc *src = GST_RTMP_SRC (basesrc); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_URI: gst_query_set_uri (query, src->uri); ret = TRUE; break; case GST_QUERY_POSITION:{ GstFormat format; gst_query_parse_position (query, &format, NULL); if (format == GST_FORMAT_TIME) { gst_query_set_duration (query, format, src->last_timestamp); ret = TRUE; } break; } case GST_QUERY_DURATION:{ GstFormat format; gdouble duration; gst_query_parse_duration (query, &format, NULL); if (format == GST_FORMAT_TIME && src->rtmp) { duration = RTMP_GetDuration (src->rtmp); if (duration != 0.0) { gst_query_set_duration (query, format, duration * GST_SECOND); ret = TRUE; } } break; } default: ret = FALSE; break; } if (!ret) ret = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query); return ret; }
static gboolean gst_wildmidi_src_query (GstPad * pad, GstQuery * query) { gboolean res = TRUE; GstWildmidi *wildmidi = GST_WILDMIDI (gst_pad_get_parent (pad)); GstFormat src_format, dst_format; gint64 src_value, dst_value; if (!wildmidi->song) { gst_object_unref (wildmidi); return FALSE; } switch (GST_QUERY_TYPE (query)) { case GST_QUERY_DURATION: gst_query_set_duration (query, GST_FORMAT_TIME, gst_util_uint64_scale_int (wildmidi->o_len, GST_SECOND, WILDMIDI_RATE)); break; case GST_QUERY_POSITION: gst_query_set_position (query, GST_FORMAT_TIME, gst_util_uint64_scale_int (wildmidi->o_segment->last_stop, GST_SECOND, WILDMIDI_RATE)); break; case GST_QUERY_CONVERT: gst_query_parse_convert (query, &src_format, &src_value, &dst_format, NULL); res = gst_wildmidi_src_convert (wildmidi, src_format, src_value, &dst_format, &dst_value); if (res) gst_query_set_convert (query, src_format, src_value, dst_format, dst_value); break; case GST_QUERY_FORMATS: gst_query_set_formats (query, 3, GST_FORMAT_TIME, GST_FORMAT_BYTES, GST_FORMAT_DEFAULT); break; case GST_QUERY_SEGMENT: gst_query_set_segment (query, wildmidi->o_segment->rate, wildmidi->o_segment->format, wildmidi->o_segment->start, wildmidi->o_segment->stop); break; case GST_QUERY_SEEKING: gst_query_set_seeking (query, wildmidi->o_segment->format, TRUE, 0, wildmidi->o_len); break; default: res = FALSE; break; } gst_object_unref (wildmidi); return res; }
static gboolean speex_dec_src_query (GstPad * pad, GstQuery * query) { GstSpeexDec *dec; gboolean res = FALSE; dec = GST_SPEEX_DEC (gst_pad_get_parent (pad)); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION:{ GstSegment segment; GstFormat format; gint64 cur; gst_query_parse_position (query, &format, NULL); GST_PAD_STREAM_LOCK (dec->sinkpad); segment = dec->segment; GST_PAD_STREAM_UNLOCK (dec->sinkpad); if (segment.format != GST_FORMAT_TIME) { GST_DEBUG_OBJECT (dec, "segment not initialised yet"); break; } if ((res = speex_dec_convert (dec->srcpad, GST_FORMAT_TIME, segment.last_stop, &format, &cur))) { gst_query_set_position (query, format, cur); } break; } case GST_QUERY_DURATION:{ GstFormat format = GST_FORMAT_TIME; gint64 dur; /* get duration from demuxer */ if (!gst_pad_query_peer_duration (dec->sinkpad, &format, &dur)) break; gst_query_parse_duration (query, &format, NULL); /* and convert it into the requested format */ if ((res = speex_dec_convert (dec->srcpad, GST_FORMAT_TIME, dur, &format, &dur))) { gst_query_set_duration (query, format, dur); } break; } default: res = gst_pad_query_default (pad, query); break; } gst_object_unref (dec); return res; }
static gboolean gst_timidity_src_query (GstPad * pad, GstQuery * query) { gboolean res = TRUE; GstTimidity *timidity = GST_TIMIDITY (gst_pad_get_parent (pad)); GstFormat src_format, dst_format; gint64 src_value, dst_value; if (!timidity->song) { gst_object_unref (timidity); return FALSE; } switch (GST_QUERY_TYPE (query)) { case GST_QUERY_DURATION: gst_query_set_duration (query, GST_FORMAT_TIME, GST_MSECOND * (gint64) mid_song_get_total_time (timidity->song)); break; case GST_QUERY_POSITION: gst_query_set_position (query, GST_FORMAT_TIME, timidity->o_segment->last_stop * timidity->time_per_frame); break; case GST_QUERY_CONVERT: gst_query_parse_convert (query, &src_format, &src_value, &dst_format, NULL); res = gst_timidity_src_convert (timidity, src_format, src_value, &dst_format, &dst_value); if (res) gst_query_set_convert (query, src_format, src_value, dst_format, dst_value); break; case GST_QUERY_FORMATS: gst_query_set_formats (query, 3, GST_FORMAT_TIME, GST_FORMAT_BYTES, GST_FORMAT_DEFAULT); break; case GST_QUERY_SEGMENT: gst_query_set_segment (query, timidity->o_segment->rate, timidity->o_segment->format, timidity->o_segment->start, timidity->o_segment->stop); break; case GST_QUERY_SEEKING: gst_query_set_seeking (query, timidity->o_segment->format, TRUE, 0, timidity->o_len); break; default: res = FALSE; break; } gst_object_unref (timidity); return res; }
static gboolean gst_real_audio_demux_src_query (GstPad * pad, GstQuery * query) { GstRealAudioDemux *demux; gboolean ret = FALSE; demux = GST_REAL_AUDIO_DEMUX (gst_pad_get_parent (pad)); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_DURATION:{ GstFormat format; gst_query_parse_duration (query, &format, NULL); if (format == GST_FORMAT_TIME && demux->duration > 0) { gst_query_set_duration (query, GST_FORMAT_TIME, demux->duration); ret = TRUE; } else if (format == GST_FORMAT_BYTES && demux->upstream_size > 0) { gst_query_set_duration (query, GST_FORMAT_BYTES, demux->upstream_size - demux->data_offset); ret = TRUE; } break; } case GST_QUERY_SEEKING:{ GstFormat format; gboolean seekable; gst_query_parse_seeking (query, &format, NULL, NULL, NULL); seekable = (format == GST_FORMAT_TIME && demux->seekable); gst_query_set_seeking (query, format, seekable, 0, (format == GST_FORMAT_TIME) ? demux->duration : -1); ret = TRUE; break; } default: ret = gst_pad_query_default (pad, query); break; } gst_object_unref (demux); return ret; }
static gboolean gst_rtmp_src_query (GstBaseSrc * basesrc, GstQuery * query) { gboolean ret = FALSE; GstRTMPSrc *src = GST_RTMP_SRC (basesrc); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_URI: gst_query_set_uri (query, src->uri); ret = TRUE; break; case GST_QUERY_POSITION:{ GstFormat format; gst_query_parse_position (query, &format, NULL); if (format == GST_FORMAT_TIME) { gst_query_set_position (query, format, src->last_timestamp); ret = TRUE; } break; } case GST_QUERY_DURATION:{ GstFormat format; gdouble duration; gst_query_parse_duration (query, &format, NULL); if (format == GST_FORMAT_TIME && src->rtmp) { duration = RTMP_GetDuration (src->rtmp); if (duration != 0.0) { gst_query_set_duration (query, format, duration * GST_SECOND); ret = TRUE; } } break; } case GST_QUERY_SCHEDULING:{ gst_query_set_scheduling (query, GST_SCHEDULING_FLAG_SEQUENTIAL | GST_SCHEDULING_FLAG_BANDWIDTH_LIMITED, 1, -1, 0); gst_query_add_scheduling_mode (query, GST_PAD_MODE_PUSH); ret = TRUE; break; } default: ret = FALSE; break; } if (!ret) ret = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query); return ret; }
static gboolean gst_vcd_parse_src_query (GstPad * pad, GstQuery * query) { GstVcdParse *vcd = GST_VCD_PARSE (gst_pad_get_parent (pad)); gboolean res = FALSE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_DURATION:{ GstFormat format; gint64 dur; /* first try upstream */ if (!gst_pad_query_default (pad, query)) break; /* we can only handle BYTES */ gst_query_parse_duration (query, &format, &dur); if (format != GST_FORMAT_BYTES) break; gst_query_set_duration (query, GST_FORMAT_BYTES, gst_vcd_parse_get_out_offset (dur)); res = TRUE; break; } case GST_QUERY_POSITION:{ GstFormat format; gint64 pos; /* first try upstream */ if (!gst_pad_query_default (pad, query)) break; /* we can only handle BYTES */ gst_query_parse_position (query, &format, &pos); if (format != GST_FORMAT_BYTES) break; gst_query_set_position (query, GST_FORMAT_BYTES, gst_vcd_parse_get_out_offset (pos)); res = TRUE; break; } default: res = gst_pad_query_default (pad, query); break; } gst_object_unref (vcd); return res; }
static gboolean gst_tta_parse_query (GstPad * pad, GstQuery * query) { GstTtaParse *ttaparse = GST_TTA_PARSE (gst_pad_get_parent (pad)); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: { GstFormat format; gint64 cur; gst_query_parse_position (query, &format, NULL); switch (format) { case GST_FORMAT_TIME: cur = ttaparse->index[ttaparse->current_frame].time; break; default: format = GST_FORMAT_BYTES; cur = ttaparse->index[ttaparse->current_frame].pos; break; } gst_query_set_position (query, format, cur); break; } case GST_QUERY_DURATION: { GstFormat format; gint64 end; gst_query_parse_duration (query, &format, NULL); switch (format) { case GST_FORMAT_TIME: end = ((gdouble) ttaparse->data_length / (gdouble) ttaparse->samplerate) * GST_SECOND; break; default: format = GST_FORMAT_BYTES; end = ttaparse->index[ttaparse->num_frames].pos + ttaparse->index[ttaparse->num_frames].size; break; } gst_query_set_duration (query, format, end); break; } default: return FALSE; break; } return TRUE; }
static gboolean _src_query (GstPad * pad, GstObject * parent, GstQuery * query) { GstFormat fmt; if (GST_QUERY_TYPE (query) != GST_QUERY_DURATION) return FALSE; gst_query_parse_duration (query, &fmt, NULL); if (fmt != GST_FORMAT_BYTES) return FALSE; gst_query_set_duration (query, fmt, sizeof (mxf_file)); return TRUE; }
/*********************************************************************************** * Query ***********************************************************************************/ static gboolean mpegts_demuxer_sink_query (GstPad *pad, GstObject *parent, GstQuery *query) { gboolean result = TRUE; MpegTSDemuxer *demuxer = MPEGTS_DEMUXER(parent); switch (GST_QUERY_TYPE(query)) { case GST_QUERY_DURATION: { GstFormat format; gst_query_parse_duration(query, &format, NULL); if (format == GST_FORMAT_TIME) result = gst_pad_peer_query(pad, query); else if (format == GST_FORMAT_BYTES) { g_mutex_lock(&demuxer->lock); int bit_rate = (demuxer->context != NULL) ? demuxer->context->bit_rate : 0; g_mutex_unlock(&demuxer->lock); if (bit_rate > 0) { gint64 duration = GST_CLOCK_TIME_NONE; if (gst_pad_peer_query_duration(pad, GST_FORMAT_TIME, &duration)) { // Approximate duration in bytes for a certain time duration and bit rate. if (duration != GST_CLOCK_TIME_NONE) duration = (double)(duration * bit_rate) / GST_SECOND / 8; gst_query_set_duration(query, format, duration); } else result = FALSE; } else result = gst_pad_peer_query(pad, query); } break; } default: result = gst_pad_peer_query(pad, query); break; } return result; }
static gboolean gst_deinterleave_src_query (GstPad * pad, GstObject * parent, GstQuery * query) { GstDeinterleave *self = GST_DEINTERLEAVE (parent); gboolean res; res = gst_pad_query_default (pad, parent, query); if (res && GST_QUERY_TYPE (query) == GST_QUERY_DURATION) { GstFormat format; gint64 dur; gst_query_parse_duration (query, &format, &dur); /* Need to divide by the number of channels in byte format * to get the correct value. All other formats should be fine */ if (format == GST_FORMAT_BYTES && dur != -1) gst_query_set_duration (query, format, dur / GST_AUDIO_INFO_CHANNELS (&self->audio_info)); } else if (res && GST_QUERY_TYPE (query) == GST_QUERY_POSITION) { GstFormat format; gint64 pos; gst_query_parse_position (query, &format, &pos); /* Need to divide by the number of channels in byte format * to get the correct value. All other formats should be fine */ if (format == GST_FORMAT_BYTES && pos != -1) gst_query_set_position (query, format, pos / GST_AUDIO_INFO_CHANNELS (&self->audio_info)); } else if (res && GST_QUERY_TYPE (query) == GST_QUERY_CAPS) { GstCaps *filter, *caps; gst_query_parse_caps (query, &filter); caps = gst_deinterleave_sink_getcaps (pad, parent, filter); gst_query_set_caps_result (query, caps); gst_caps_unref (caps); } return res; }
static gboolean gst_mms_src_query (GstPad * pad, GstQuery * query) { GstMMS *mmssrc = GST_MMS (gst_pad_get_parent (pad)); gboolean res = TRUE; GstFormat format; gint64 value; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: gst_query_parse_position (query, &format, &value); if (format != GST_FORMAT_BYTES) { res = FALSE; break; } if (mmssrc->connection) { value = (gint64) mms_get_current_pos (mmssrc->connection); } else { value = (gint64) mmsh_get_current_pos (mmssrc->connection_h); } gst_query_set_position (query, format, value); break; case GST_QUERY_DURATION: gst_query_parse_duration (query, &format, &value); if (format != GST_FORMAT_BYTES) { res = FALSE; break; } if (mmssrc->connection) { value = (gint64) mms_get_length (mmssrc->connection); } else { value = (gint64) mmsh_get_length (mmssrc->connection_h); } gst_query_set_duration (query, format, value); break; default: res = FALSE; break; } gst_object_unref (mmssrc); return res; }
/* FIXME: * * When we add a new stream (or remove a stream) the duration might * also become invalid again and we need to post a new DURATION * message to notify this fact to the parent. * For now we take the max of all the upstream elements so the simple * cases work at least somewhat. */ static gboolean gst_live_adder_query_duration (GstLiveAdder * adder, GstQuery * query) { GstFormat format; gint64 max; gboolean res; /* parse format */ gst_query_parse_duration (query, &format, NULL); res = gst_live_adder_query_pos_dur (adder, format, FALSE, &max); if (res) { /* and store the max */ gst_query_set_duration (query, format, max); } return res; }
static gboolean gst_spc_dec_src_query (GstPad * pad, GstQuery * query) { GstSpcDec *spc = GST_SPC_DEC (gst_pad_get_parent (pad)); gboolean result = TRUE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_DURATION: { GstFormat format; gst_query_parse_duration (query, &format, NULL); if (!spc->initialized || format != GST_FORMAT_TIME) { result = FALSE; break; } gst_query_set_duration (query, GST_FORMAT_TIME, gst_spc_duration (spc) + gst_spc_fadeout (spc)); break; } case GST_QUERY_POSITION: { GstFormat format; gst_query_parse_position (query, &format, NULL); if (!spc->initialized || format != GST_FORMAT_TIME) { result = FALSE; break; } gst_query_set_position (query, GST_FORMAT_TIME, (gint64) gst_util_uint64_scale (spc->byte_pos, GST_SECOND, 32000 * 2 * 2)); break; } default: result = gst_pad_query_default (pad, query); break; } gst_object_unref (spc); return result; }
static gboolean gst_gme_dec_src_query (GstPad * pad, GstObject * parent, GstQuery * query) { GstGmeDec *gme = GST_GME_DEC (parent); gboolean result = TRUE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_DURATION: { GstFormat format; gst_query_parse_duration (query, &format, NULL); if (!gme->initialized || format != GST_FORMAT_TIME || gme->total_duration == GST_CLOCK_TIME_NONE) { result = FALSE; break; } gst_query_set_duration (query, GST_FORMAT_TIME, gme->total_duration); break; } case GST_QUERY_POSITION: { GstFormat format; gst_query_parse_position (query, &format, NULL); if (!gme->initialized || format != GST_FORMAT_TIME) { result = FALSE; break; } gst_query_set_position (query, GST_FORMAT_TIME, (gint64) gme_tell (gme->player) * GST_MSECOND); break; } default: result = gst_pad_query_default (pad, parent, query); break; } return result; }
static gboolean gst_cdxa_parse_src_query (GstPad * srcpad, GstQuery * query) { GstCDXAParse *cdxa = GST_CDXA_PARSE (gst_pad_get_parent (srcpad)); gboolean res = FALSE; GST_DEBUG_OBJECT (cdxa, "Handling %s query", gst_query_type_get_name (GST_QUERY_TYPE (query))); res = gst_pad_query_default (srcpad, query); if (res) { GstFormat format; gint64 val; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_DURATION: gst_query_parse_duration (query, &format, &val); if (format == GST_FORMAT_BYTES) { val = gst_cdxa_parse_convert_sink_to_src_offset (cdxa, val); gst_query_set_duration (query, format, val); } break; case GST_QUERY_POSITION: gst_query_parse_position (query, &format, &val); if (format == GST_FORMAT_BYTES) { val = gst_cdxa_parse_convert_sink_to_src_offset (cdxa, val); gst_query_set_position (query, format, val); } break; default: break; } } gst_object_unref (cdxa); return res; }
static gboolean gst_ts_demux_srcpad_query (GstPad * pad, GstQuery * query) { gboolean res = TRUE; GstTSDemux *demux; demux = GST_TS_DEMUX (gst_pad_get_parent (pad)); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_DURATION: { GstFormat format; gst_query_parse_duration (query, &format, NULL); /* can only get position in time */ if (format != GST_FORMAT_TIME) goto wrong_format; gst_query_set_duration (query, GST_FORMAT_TIME, demux->duration); break; } default: res = gst_pad_query_default (pad, query); break; } done: gst_object_unref (demux); return res; wrong_format: { GST_DEBUG_OBJECT (demux, "only query duration on TIME is supported"); res = FALSE; goto done; } }
static gboolean gst_ss_demux_handle_src_query (GstPad * pad, GstQuery * query) { gboolean res = FALSE; GstSSDemux *ssdemux = GST_SS_DEMUX (gst_pad_get_parent (pad)); GST_LOG_OBJECT (pad, "%s query", GST_QUERY_TYPE_NAME (query)); // TODO: need to add other query types as well switch (GST_QUERY_TYPE (query)) { case GST_QUERY_DURATION:{ GstFormat fmt; gst_query_parse_duration (query, &fmt, NULL); if (fmt == GST_FORMAT_TIME) { gint64 duration = -1; duration = gst_util_uint64_scale (GST_SSM_PARSE_GET_DURATION(ssdemux->parser), GST_SECOND, GST_SSM_PARSE_GET_TIMESCALE(ssdemux->parser)); if (duration > 0) { gst_query_set_duration (query, GST_FORMAT_TIME, duration); res = TRUE; } } break; } default: res = gst_pad_query_default (pad, query); break; } gst_object_unref (ssdemux); return res; }
/* handle queries for location and length in requested format */ static gboolean gst_aiff_parse_pad_query (GstPad * pad, GstQuery * query) { gboolean res = TRUE; GstAiffParse *aiff = GST_AIFF_PARSE (gst_pad_get_parent (pad)); /* only if we know */ if (aiff->state != AIFF_PARSE_DATA) { gst_object_unref (aiff); return FALSE; } switch (GST_QUERY_TYPE (query)) { case GST_QUERY_DURATION: { gint64 duration = 0; GstFormat format; gst_query_parse_duration (query, &format, NULL); switch (format) { case GST_FORMAT_TIME:{ if ((res = gst_aiff_parse_calculate_duration (aiff))) { duration = aiff->duration; } break; } default: format = GST_FORMAT_BYTES; duration = aiff->datasize; break; } gst_query_set_duration (query, format, duration); break; } case GST_QUERY_CONVERT: { gint64 srcvalue, dstvalue; GstFormat srcformat, dstformat; gst_query_parse_convert (query, &srcformat, &srcvalue, &dstformat, &dstvalue); res = gst_aiff_parse_pad_convert (pad, srcformat, srcvalue, &dstformat, &dstvalue); if (res) gst_query_set_convert (query, srcformat, srcvalue, dstformat, dstvalue); break; } case GST_QUERY_SEEKING:{ GstFormat fmt; gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL); if (fmt == GST_FORMAT_TIME) { gboolean seekable = TRUE; if (!gst_aiff_parse_calculate_duration (aiff)) { seekable = FALSE; } gst_query_set_seeking (query, GST_FORMAT_TIME, seekable, 0, aiff->duration); res = TRUE; } break; } default: res = gst_pad_query_default (pad, query); break; } gst_object_unref (aiff); return res; }
static gboolean gst_musepackdec_src_query (GstPad * pad, GstObject * parent, GstQuery * query) { GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (parent); GstFormat format; gboolean res = FALSE; gint samplerate; samplerate = g_atomic_int_get (&musepackdec->rate); if (samplerate == 0) goto done; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION:{ gint64 cur, cur_off; gst_query_parse_position (query, &format, NULL); GST_OBJECT_LOCK (musepackdec); cur_off = musepackdec->segment.position; GST_OBJECT_UNLOCK (musepackdec); if (format == GST_FORMAT_TIME) { cur = gst_util_uint64_scale_int (cur_off, GST_SECOND, samplerate); gst_query_set_position (query, GST_FORMAT_TIME, cur); res = TRUE; } else if (format == GST_FORMAT_DEFAULT) { gst_query_set_position (query, GST_FORMAT_DEFAULT, cur_off); res = TRUE; } break; } case GST_QUERY_DURATION:{ gint64 len, len_off; gst_query_parse_duration (query, &format, NULL); GST_OBJECT_LOCK (musepackdec); len_off = musepackdec->segment.duration; GST_OBJECT_UNLOCK (musepackdec); if (format == GST_FORMAT_TIME) { len = gst_util_uint64_scale_int (len_off, GST_SECOND, samplerate); gst_query_set_duration (query, GST_FORMAT_TIME, len); res = TRUE; } else if (format == GST_FORMAT_DEFAULT) { gst_query_set_duration (query, GST_FORMAT_DEFAULT, len_off); res = TRUE; } break; } case GST_QUERY_SEEKING:{ GstFormat fmt; gint64 len, len_off; res = TRUE; gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL); GST_OBJECT_LOCK (musepackdec); len_off = musepackdec->segment.duration; GST_OBJECT_UNLOCK (musepackdec); if (fmt == GST_FORMAT_TIME) { len = gst_util_uint64_scale_int (len_off, GST_SECOND, samplerate); gst_query_set_seeking (query, fmt, TRUE, 0, len); } else if (fmt == GST_FORMAT_DEFAULT) { gst_query_set_seeking (query, fmt, TRUE, 0, len_off); } else { gst_query_set_seeking (query, fmt, FALSE, -1, -1); } break; } default: res = gst_pad_query_default (pad, parent, query); break; } done: return res; }
/* FIXME, the duration query should reflect how long you will produce * data, that is the amount of stream time until you will emit EOS. * * For synchronized mixing this is always the max of all the durations * of upstream since we emit EOS when all of them finished. * * We don't do synchronized mixing so this really depends on where the * streams where punched in and what their relative offsets are against * eachother which we can get from the first timestamps we see. * * When we add a new stream (or remove a stream) the duration might * also become invalid again and we need to post a new DURATION * message to notify this fact to the parent. * For now we take the max of all the upstream elements so the simple * cases work at least somewhat. */ static gboolean gst_adder_query_duration (GstAdder * adder, GstQuery * query) { gint64 max; gboolean res; GstFormat format; GstIterator *it; gboolean done; /* parse format */ gst_query_parse_duration (query, &format, NULL); max = -1; res = TRUE; done = FALSE; it = gst_element_iterate_sink_pads (GST_ELEMENT_CAST (adder)); while (!done) { GstIteratorResult ires; gpointer item; 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 duration; /* ask sink peer for duration */ res &= gst_pad_query_peer_duration (pad, &format, &duration); /* take max from all valid return values */ if (res) { /* valid unknown length, stop searching */ if (duration == -1) { max = duration; done = TRUE; } /* else see if bigger than current max */ else if (duration > max) max = duration; } gst_object_unref (pad); break; } case GST_ITERATOR_RESYNC: max = -1; res = TRUE; gst_iterator_resync (it); break; default: res = FALSE; done = TRUE; break; } } gst_iterator_free (it); if (res) { /* and store the max */ GST_DEBUG_OBJECT (adder, "Total duration in format %s: %" GST_TIME_FORMAT, gst_format_get_name (format), GST_TIME_ARGS (max)); gst_query_set_duration (query, format, max); } return res; }
static gboolean gst_wildmidi_src_query (GstPad * pad, GstObject * parent, GstQuery * query) { gboolean res = TRUE; GstWildmidi *wildmidi = GST_WILDMIDI (parent); GstFormat src_format, dst_format; gint64 src_value, dst_value; if (!wildmidi->song) return FALSE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_DURATION: gst_query_set_duration (query, GST_FORMAT_TIME, gst_util_uint64_scale_int (wildmidi->o_len, GST_SECOND, WILDMIDI_RATE)); break; case GST_QUERY_POSITION: gst_query_set_position (query, GST_FORMAT_TIME, gst_util_uint64_scale_int (wildmidi->o_segment->position, GST_SECOND, WILDMIDI_RATE)); break; case GST_QUERY_CONVERT: gst_query_parse_convert (query, &src_format, &src_value, &dst_format, NULL); res = gst_wildmidi_src_convert (wildmidi, src_format, src_value, &dst_format, &dst_value); if (res) gst_query_set_convert (query, src_format, src_value, dst_format, dst_value); break; case GST_QUERY_FORMATS: gst_query_set_formats (query, 3, GST_FORMAT_TIME, GST_FORMAT_BYTES, GST_FORMAT_DEFAULT); break; case GST_QUERY_SEGMENT:{ GstFormat format; gint64 start, stop; format = wildmidi->o_segment->format; start = gst_segment_to_stream_time (wildmidi->o_segment, format, wildmidi->o_segment->start); if ((stop = wildmidi->o_segment->stop) == -1) stop = wildmidi->o_segment->duration; else stop = gst_segment_to_stream_time (wildmidi->o_segment, format, stop); gst_query_set_segment (query, wildmidi->o_segment->rate, format, start, stop); res = TRUE; break; } case GST_QUERY_SEEKING: gst_query_set_seeking (query, wildmidi->o_segment->format, TRUE, 0, wildmidi->o_len); break; default: res = gst_pad_query_default (pad, parent, query); break; } return res; }