/* 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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}
static gboolean
gst_frei0r_mixer_src_query_duration (GstFrei0rMixer * self, GstQuery * query)
{
  gint64 min;
  gboolean res;
  GstFormat format;
  GstIterator *it;
  gboolean done;

  /* parse format */
  gst_query_parse_duration (query, &format, NULL);

  min = -1;
  res = TRUE;
  done = FALSE;

  /* Take minimum of all durations */
  it = gst_element_iterate_sink_pads (GST_ELEMENT_CAST (self));
  while (!done) {
    GstIteratorResult ires;
    GValue item = { 0 };

    ires = gst_iterator_next (it, &item);
    switch (ires) {
      case GST_ITERATOR_DONE:
        done = TRUE;
        break;
      case GST_ITERATOR_OK:
      {
        GstPad *pad = g_value_get_object (&item);
        gint64 duration;

        /* ask sink peer for duration */
        res &= gst_pad_peer_query_duration (pad, format, &duration);
        /* take min from all valid return values */
        if (res) {
          /* valid unknown length, stop searching */
          if (duration == -1) {
            min = duration;
            done = TRUE;
          }
          /* else see if smaller than current min */
          else if (duration < min)
            min = duration;
        }
        g_value_reset (&item);
        break;
      }
      case GST_ITERATOR_RESYNC:
        min = -1;
        res = TRUE;
        gst_iterator_resync (it);
        break;
      default:
        res = FALSE;
        done = TRUE;
        break;
    }

    g_value_unset (&item);
  }
  gst_iterator_free (it);

  if (res) {
    /* and store the min */
    GST_DEBUG_OBJECT (self, "Total duration in format %s: %"
        GST_TIME_FORMAT, gst_format_get_name (format), GST_TIME_ARGS (min));
    gst_query_set_duration (query, format, min);
  }

  return res;
}
static gboolean
gst_interleave_src_query_duration (GstInterleave * self, 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;

  /* Take maximum of all durations */
  it = gst_element_iterate_sink_pads (GST_ELEMENT_CAST (self));
  while (!done) {
    GstIteratorResult ires;

    GValue item = { 0, };

    ires = gst_iterator_next (it, &item);
    switch (ires) {
      case GST_ITERATOR_DONE:
        done = TRUE;
        break;
      case GST_ITERATOR_OK:
      {
        GstPad *pad = GST_PAD_CAST (g_value_dup_object (&item));

        gint64 duration;

        /* ask sink peer for duration */
        res &= gst_pad_peer_query_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);
        g_value_unset (&item);
        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) {
    /* If in bytes format we have to multiply with the number of channels
     * to get the correct results. All other formats should be fine */
    if (format == GST_FORMAT_BYTES && max != -1)
      max *= self->channels;

    /* and store the max */
    GST_DEBUG_OBJECT (self, "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_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;
}
Beispiel #13
0
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;
}
Beispiel #14
0
static gboolean
gst_cdaudio_query (GstElement * element, GstQuery * query)
{
  GstCDAudio *cdaudio;
  gboolean res = TRUE;
  gulong micros;
  gdouble seconds;

  cdaudio = GST_CDAUDIO (element);

  GST_LOG_OBJECT (element, "handling %s query",
      gst_query_type_get_name (GST_QUERY_TYPE (query)));

  /* take new snapshot every 1000 miliseconds */
  seconds = g_timer_elapsed (cdaudio->timer, &micros);
  if (micros > 1000 || seconds > 1) {
    cd_stat (cdaudio->cd_desc, &cdaudio->info);
    g_timer_start (cdaudio->timer);
  }

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_DURATION:
    {
      GstFormat dest_format;
      gint64 dest_val;

      gst_query_parse_duration (query, &dest_format, NULL);

      switch (dest_format) {
        case GST_FORMAT_TIME:
          dest_val = (cdaudio->info.disc_length.minutes * 60 +
              cdaudio->info.disc_length.seconds) * GST_SECOND;
          break;
        default:
        {
          if (dest_format == track_format) {
            dest_val = cdaudio->info.disc_total_tracks;
          } else {
            res = FALSE;
          }
          break;
        }
      }
      if (res)
        gst_query_set_duration (query, dest_format, dest_val);
      break;
    }
    case GST_QUERY_POSITION:
    {
      GstFormat dest_format;
      gint64 dest_val;

      gst_query_parse_position (query, &dest_format, NULL);

      switch (dest_format) {
        case GST_FORMAT_TIME:
          dest_val = (cdaudio->info.disc_time.minutes * 60 +
              cdaudio->info.disc_time.seconds) * GST_SECOND;
          break;
        default:
        {
          if (dest_format == track_format) {
            dest_val = cdaudio->info.disc_current_track;
          } else {
            res = FALSE;
          }
          break;
        }
      }
      if (res)
        gst_query_set_position (query, dest_format, dest_val);
      break;
    }
    default:
      res = FALSE;
      break;
  }
  return res;
}
static gboolean
gst_raw_parse_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  GstRawParse *rp = GST_RAW_PARSE (parent);
  gboolean ret = FALSE;

  GST_DEBUG ("src_query %s", gst_query_type_get_name (GST_QUERY_TYPE (query)));

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
    {
      GstFormat format;
      gint64 time, value;

      GST_LOG ("query position");

      gst_query_parse_position (query, &format, NULL);

      time = rp->segment.position;
      ret = gst_raw_parse_convert (rp, GST_FORMAT_TIME, time, format, &value);

      gst_query_set_position (query, format, value);

      break;
    }
    case GST_QUERY_DURATION:{
      gint64 duration;
      GstFormat format;
      GstQuery *bquery;

      GST_LOG ("query duration");
      ret = gst_pad_peer_query (rp->sinkpad, query);
      if (ret)
        goto done;

      gst_query_parse_duration (query, &format, NULL);
      /* We only handle TIME and DEFAULT format */
      if (format != GST_FORMAT_TIME && format != GST_FORMAT_DEFAULT)
        goto error;

      bquery = gst_query_new_duration (GST_FORMAT_BYTES);
      ret = gst_pad_peer_query (rp->sinkpad, bquery);
      if (!ret) {
        gst_query_unref (bquery);
        goto error;
      }

      gst_query_parse_duration (bquery, NULL, &duration);
      gst_query_unref (bquery);

      ret =
          gst_raw_parse_convert (rp, GST_FORMAT_BYTES, duration, format,
          &duration);
      if (ret)
        gst_query_set_duration (query, format, duration);

      break;
    }
    case GST_QUERY_CONVERT:
    {
      GstFormat src_fmt, dest_fmt;
      gint64 src_val, dest_val;

      GST_LOG ("query convert");

      gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
      ret = gst_raw_parse_convert (rp, src_fmt, src_val, dest_fmt, &dest_val);
      if (!ret)
        goto error;
      gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
      break;
    }
    case GST_QUERY_SEEKING:{
      GstFormat fmt;

      ret = TRUE;
      gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
      if (fmt != GST_FORMAT_TIME && fmt != GST_FORMAT_DEFAULT
          && fmt != GST_FORMAT_BYTES) {
        gst_query_set_seeking (query, fmt, FALSE, -1, -1);
      } else if (rp->mode == GST_PAD_MODE_PUSH) {
        GstQuery *peerquery = gst_query_new_seeking (GST_FORMAT_BYTES);
        gboolean seekable;

        seekable = gst_pad_peer_query (rp->sinkpad, peerquery);
        if (seekable)
          gst_query_parse_seeking (peerquery, NULL, &seekable, NULL, NULL);

        gst_query_unref (peerquery);
        gst_query_set_seeking (query, fmt, seekable, seekable ? 0 : -1, -1);
      } else {
        gst_query_set_seeking (query, fmt, TRUE, 0, -1);
      }
      break;
    }
    default:
      /* else forward upstream */
      ret = gst_pad_query_default (rp->sinkpad, parent, query);
      break;
  }

done:
  return ret;

  /* ERRORS */
error:
  {
    GST_DEBUG_OBJECT (rp, "query failed");
    goto done;
  }
}
Beispiel #16
0
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_image_freeze_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
    GstImageFreeze *self = GST_IMAGE_FREEZE (parent);
    gboolean ret = FALSE;

    GST_LOG_OBJECT (pad, "Handling query of type '%s'",
                    gst_query_type_get_name (GST_QUERY_TYPE (query)));

    switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_CONVERT: {
        GstFormat src_format, dest_format;
        gint64 src_value, dest_value;

        gst_query_parse_convert (query, &src_format, &src_value, &dest_format,
                                 &dest_value);
        ret =
            gst_image_freeze_convert (self, src_format, src_value, &dest_format,
                                      &dest_value);
        if (ret)
            gst_query_set_convert (query, src_format, src_value, dest_format,
                                   dest_value);
        break;
    }
    case GST_QUERY_POSITION: {
        GstFormat format;
        gint64 position;

        gst_query_parse_position (query, &format, NULL);
        switch (format) {
        case GST_FORMAT_DEFAULT: {
            g_mutex_lock (&self->lock);
            position = self->offset;
            g_mutex_unlock (&self->lock);
            ret = TRUE;
            break;
        }
        case GST_FORMAT_TIME: {
            g_mutex_lock (&self->lock);
            position = self->segment.position;
            g_mutex_unlock (&self->lock);
            ret = TRUE;
            break;
        }
        default:
            break;
        }

        if (ret) {
            gst_query_set_position (query, format, position);
            GST_DEBUG_OBJECT (pad,
                              "Returning position %" G_GINT64_FORMAT " in format %s", position,
                              gst_format_get_name (format));
        } else {
            GST_DEBUG_OBJECT (pad, "Position query failed");
        }
        break;
    }
    case GST_QUERY_DURATION: {
        GstFormat format;
        gint64 duration;

        gst_query_parse_duration (query, &format, NULL);
        switch (format) {
        case GST_FORMAT_TIME: {
            g_mutex_lock (&self->lock);
            duration = self->segment.stop;
            g_mutex_unlock (&self->lock);
            ret = TRUE;
            break;
        }
        case GST_FORMAT_DEFAULT: {
            g_mutex_lock (&self->lock);
            duration = self->segment.stop;
            if (duration != -1)
                duration =
                    gst_util_uint64_scale (duration, self->fps_n,
                                           GST_SECOND * self->fps_d);
            g_mutex_unlock (&self->lock);
            ret = TRUE;
            break;
        }
        default:
            break;
        }

        if (ret) {
            gst_query_set_duration (query, format, duration);
            GST_DEBUG_OBJECT (pad,
                              "Returning duration %" G_GINT64_FORMAT " in format %s", duration,
                              gst_format_get_name (format));
        } else {
            GST_DEBUG_OBJECT (pad, "Duration query failed");
        }
        break;
    }
    case GST_QUERY_SEEKING: {
        GstFormat format;
        gboolean seekable;

        gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
        seekable = (format == GST_FORMAT_TIME || format == GST_FORMAT_DEFAULT);

        gst_query_set_seeking (query, format, seekable, (seekable ? 0 : -1), -1);
        ret = TRUE;
        break;
    }
    default:
        ret = FALSE;
        break;
    }

    return ret;
}
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;
}
Beispiel #19
0
static gboolean
gst_real_audio_demux_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query)
{
  GstRealAudioDemux *demux;
  gboolean ret = FALSE;

  demux = GST_REAL_AUDIO_DEMUX (parent);

  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;
    }
    case GST_QUERY_SEGMENT:
    {
      GstFormat format;
      gint64 start, stop;

      format = demux->segment.format;

      start =
          gst_segment_to_stream_time (&demux->segment, format,
          demux->segment.start);
      if ((stop = demux->segment.stop) == -1)
        stop = demux->segment.duration;
      else
        stop = gst_segment_to_stream_time (&demux->segment, format, stop);

      gst_query_set_segment (query, demux->segment.rate, format, start, stop);
      ret = TRUE;
      break;
    }
    default:
      ret = gst_pad_query_default (pad, parent, query);
      break;
  }

  return ret;
}
Beispiel #20
0
/* 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;
}
Beispiel #21
0
static gboolean
gst_wavpack_parse_src_query (GstPad * pad, GstQuery * query)
{
  GstWavpackParse *parse = GST_WAVPACK_PARSE (gst_pad_get_parent (pad));

  GstFormat format;

  gboolean ret = FALSE;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:{
      gint64 cur;

      guint rate;

      GST_OBJECT_LOCK (parse);
      cur = parse->segment.last_stop;
      rate = parse->samplerate;
      GST_OBJECT_UNLOCK (parse);

      if (rate == 0) {
        GST_DEBUG_OBJECT (parse, "haven't read header yet");
        break;
      }

      gst_query_parse_position (query, &format, NULL);

      switch (format) {
        case GST_FORMAT_TIME:
          cur = gst_util_uint64_scale_int (cur, GST_SECOND, rate);
          gst_query_set_position (query, GST_FORMAT_TIME, cur);
          ret = TRUE;
          break;
        case GST_FORMAT_DEFAULT:
          gst_query_set_position (query, GST_FORMAT_DEFAULT, cur);
          ret = TRUE;
          break;
        default:
          GST_DEBUG_OBJECT (parse, "cannot handle position query in "
              "%s format. Forwarding upstream.", gst_format_get_name (format));
          ret = gst_pad_query_default (pad, query);
          break;
      }
      break;
    }
    case GST_QUERY_DURATION:{
      gint64 len;

      guint rate;

      GST_OBJECT_LOCK (parse);
      rate = parse->samplerate;
      len = parse->total_samples;
      GST_OBJECT_UNLOCK (parse);

      if (rate == 0) {
        GST_DEBUG_OBJECT (parse, "haven't read header yet");
        break;
      }

      gst_query_parse_duration (query, &format, NULL);

      switch (format) {
        case GST_FORMAT_TIME:
          if (len != G_GINT64_CONSTANT (-1))
            len = gst_util_uint64_scale_int (len, GST_SECOND, rate);
          gst_query_set_duration (query, GST_FORMAT_TIME, len);
          ret = TRUE;
          break;
        case GST_FORMAT_DEFAULT:
          gst_query_set_duration (query, GST_FORMAT_DEFAULT, len);
          ret = TRUE;
          break;
        default:
          GST_DEBUG_OBJECT (parse, "cannot handle duration query in "
              "%s format. Forwarding upstream.", gst_format_get_name (format));
          ret = gst_pad_query_default (pad, query);
          break;
      }
      break;
    }
    case GST_QUERY_SEEKING:{
      gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
      if (format == GST_FORMAT_TIME || format == GST_FORMAT_DEFAULT) {
        gboolean seekable;

        gint64 duration = -1;

        /* only fails if we didn't read the headers yet and can't say
         * anything about our seeking capabilities */
        if (!gst_pad_query_duration (pad, &format, &duration))
          break;

        /* can't seek in streaming mode yet */
        GST_OBJECT_LOCK (parse);
        seekable = (parse->adapter == NULL);
        GST_OBJECT_UNLOCK (parse);

        gst_query_set_seeking (query, format, seekable, 0, duration);
        ret = TRUE;
      }
      break;
    }
    default:{
      ret = gst_pad_query_default (pad, query);
      break;
    }
  }

  gst_object_unref (parse);
  return ret;

}
Beispiel #22
0
static gboolean
gst_swfdec_src_query (GstPad * pad, GstQuery * query)
{
  gboolean res = TRUE;
  GstSwfdec *swfdec;

  swfdec = GST_SWFDEC (gst_pad_get_parent (pad));

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
    {
      GstFormat format;
      gint64 value;

      gst_query_parse_position (query, &format, NULL);

      switch (format) {
        case GST_FORMAT_TIME:
          value = swfdec_render_get_frame_index (swfdec->decoder) *
              swfdec->interval;
          gst_query_set_position (query, GST_FORMAT_TIME, value);
          res = TRUE;
        default:
          res = FALSE;
          break;
      }
      break;
    }
    case GST_QUERY_DURATION:
    {
      GstFormat format;
      gint64 value;

      gst_query_parse_duration (query, &format, NULL);

      switch (format) {
        case GST_FORMAT_TIME:
        {
          int n_frames;
          int ret;

          res = FALSE;
          ret = swfdec_decoder_get_n_frames (swfdec->decoder, &n_frames);
          if (ret == SWF_OK) {
            value = n_frames * swfdec->interval;
            gst_query_set_duration (query, GST_FORMAT_TIME, value);
            res = TRUE;
          }
          break;
        }
        default:
          res = FALSE;
          break;
      }
      break;
    }
    default:
      res = FALSE;
      break;
  }

  gst_object_unref (swfdec);
  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.. */
    }
    case GST_QUERY_DURATION:
    {
      GstFormat format;
      gint64 duration;

      gst_query_parse_duration (query, &format, &duration);

      if (format != GST_FORMAT_TIME) {
        GST_DEBUG_OBJECT (videorate, "not TIME format");
        break;
      }
      GST_LOG_OBJECT (videorate, "upstream duration: %" G_GINT64_FORMAT,
          duration);
      duration = (gint64) (duration / videorate->rate);
      GST_LOG_OBJECT (videorate, "our duration: %" G_GINT64_FORMAT, duration);
      gst_query_set_duration (query, format, duration);
      res = TRUE;
      break;
    }
    case GST_QUERY_POSITION:
    {
      GstFormat dst_format;
      gint64 dst_value;

      gst_query_parse_position (query, &dst_format, &dst_value);

      if (dst_format != GST_FORMAT_TIME) {
        GST_DEBUG_OBJECT (videorate, "not TIME format");
        break;
      }
      dst_value = (gint64) (videorate->next_ts / videorate->rate);
      GST_LOG_OBJECT (videorate, "our position: %" G_GINT64_FORMAT, dst_value);
      gst_query_set_position (query, dst_format, dst_value);
      res = TRUE;
      break;
    }
    default:
      res =
          GST_BASE_TRANSFORM_CLASS (parent_class)->query (trans, direction,
          query);
      break;
  }

  return res;
}
Beispiel #24
0
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 void
test_queries (InsanityTest * test)
{
  GstQuery *query = gst_query_new_seeking (GST_FORMAT_TIME);

  if (gst_element_query (glob_pipeline, query)) {
    GstFormat fmt;
    gboolean seekable, known_seekable;

    gst_query_parse_seeking (query, &fmt, &seekable, NULL, NULL);
    if (glob_media_desc_parser == NULL) {
      insanity_test_validate_checklist_item (test, "seekable-detection",
          TRUE, "No media-descriptor file, result not verified against it");

      glob_seekable = seekable;
    } else {
      known_seekable =
          media_descriptor_parser_get_seekable (glob_media_desc_parser);

      insanity_test_validate_checklist_item (test, "seekable-detection",
          known_seekable == seekable, NULL);
      glob_seekable = known_seekable;
    }
  } else {
    if (glob_media_desc_parser != NULL)
      glob_seekable =
          media_descriptor_parser_get_seekable (glob_media_desc_parser);

    LOG (test,
        "%s Does not handle seeking queries (seekable-detection \"SKIP\")",
        gst_element_factory_get_metadata (gst_element_get_factory
            (glob_demuxer), GST_ELEMENT_METADATA_LONGNAME));
  }

  gst_query_unref (query);
  query = gst_query_new_duration (GST_FORMAT_TIME);
  if (gst_element_query (glob_pipeline, query)) {
    GstFormat fmt;
    gchar *validate_msg = NULL;
    gint64 duration;

    if (glob_media_desc_parser == NULL) {
      gst_query_parse_duration (query, &fmt, &duration);
      validate_msg =
          g_strdup_printf ("Found duration %" GST_TIME_FORMAT
          " No media-descriptor file, result not verified against it",
          GST_TIME_ARGS (duration));
      insanity_test_validate_checklist_item (test, "duration-detection",
          TRUE, validate_msg);

      g_free (validate_msg);

      glob_duration = duration;
    } else {
      glob_duration =
          media_descriptor_parser_get_duration (glob_media_desc_parser);
      gst_query_parse_duration (query, &fmt, &duration);

      if (glob_duration != duration) {
        validate_msg =
            g_strdup_printf ("Found time %" GST_TIME_FORMAT "-> %"
            GST_TIME_FORMAT, GST_TIME_ARGS (duration),
            GST_TIME_ARGS (glob_duration));

        insanity_test_validate_checklist_item (test, "duration-detection",
            glob_duration == duration, validate_msg);

        g_free (validate_msg);
      } else {
        insanity_test_validate_checklist_item (test, "duration-detection",
            TRUE, NULL);
      }
    }

  } else {
    if (glob_media_desc_parser != NULL)
      glob_duration =
          media_descriptor_parser_get_seekable (glob_media_desc_parser);

    LOG (test, "%s Does not handle duration queries "
        "(duration-detection \"SKIP\")",
        gst_element_factory_get_metadata (gst_element_get_factory
            (glob_demuxer), GST_ELEMENT_METADATA_LONGNAME));
  }

  if (GST_CLOCK_TIME_IS_VALID (glob_duration) &&
      glob_playback_duration > glob_duration) {
    LOG (test, "playback_duration > media duration, setting it"
        "to media_duration != 2");

    glob_playback_duration = glob_duration / 2;
  }
  gst_query_unref (query);


  next_test (test);
}
static gboolean
gst_ts_shifter_query (GstElement * element, GstQuery * query)
{
  gboolean ret = TRUE;
  GstTSShifter *ts = GST_TS_SHIFTER (element);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
    {
      gint64 pos = -1;
      GstFormat format;

      /* get format */
      gst_query_parse_position (query, &format, NULL);

      switch (format) {
        case GST_FORMAT_BYTES:
          pos = ts->cur_bytes;
          break;
        default:
          GST_WARNING_OBJECT (ts, "dropping query in %s format, don't "
              "know how to handle", gst_format_get_name (format));
          ret = FALSE;
          break;
      }
      /* set updated position */
      if (ret)
        gst_query_set_position (query, format, pos);
      break;
    }
    case GST_QUERY_DURATION:
    {
      GstFormat format;

      gst_query_parse_duration (query, &format, NULL);

      if (format == GST_FORMAT_BYTES) {
        GST_LOG_OBJECT (ts, "replying duration query with %" G_GUINT64_FORMAT,
            gst_ts_cache_get_total_bytes_received (ts->cache));
        gst_query_set_duration (query, GST_FORMAT_BYTES,
            gst_ts_cache_get_total_bytes_received (ts->cache));
        ret = TRUE;
      } else {
        ret = FALSE;
      }
      break;
    }
    case GST_QUERY_SEEKING:
    {
      GstFormat fmt;

      gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
      if (fmt == GST_FORMAT_BYTES) {
        gst_query_set_seeking (query, fmt, TRUE, 0, -1);
        ret = TRUE;
      } else {
        ret = FALSE;
      }
      break;
    }
    case GST_QUERY_LATENCY:
    {
      gst_query_set_latency (query, FALSE, 0, -1);
      break;
    }

    case GST_QUERY_BUFFERING:
    {
      GstFormat format;
      guint64 bytes_begin, bytes_end;

      gst_query_parse_buffering_range (query, &format, NULL, NULL, NULL);
      if (format != GST_FORMAT_BYTES) {
        ret = FALSE;
        break;
      }

      gst_ts_cache_buffered_range (ts->cache, &bytes_begin, &bytes_end);
      gst_query_set_buffering_range (query, format, bytes_begin, bytes_end, -1);

      ret = TRUE;
      break;
    }
    default:
      ret = FALSE;
      break;
  }

  return ret;
}
Beispiel #27
0
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 = -1;
      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;
        }
      }
      GST_INFO_OBJECT (hlsdemux, "GST_QUERY_DURATION returns %s with duration %"
          GST_TIME_FORMAT, ret ? "TRUE" : "FALSE", GST_TIME_ARGS (duration));
      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;
      gint64 stop = -1;

      gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
      GST_INFO_OBJECT (hlsdemux, "Received GST_QUERY_SEEKING with format %d",
          fmt);
      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,
            !gst_m3u8_client_is_live (hlsdemux->client), 0, stop);
        ret = TRUE;
        GST_INFO_OBJECT (hlsdemux, "GST_QUERY_SEEKING returning with stop : %"
            GST_TIME_FORMAT, GST_TIME_ARGS (stop));
      }
      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;
}
Beispiel #28
0
static gboolean
gst_vorbis_enc_src_query (GstPad * pad, GstQuery * query)
{
  gboolean res = TRUE;
  GstVorbisEnc *vorbisenc;
  GstPad *peerpad;

  vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad));
  peerpad = gst_pad_get_peer (GST_PAD (vorbisenc->sinkpad));

  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_position (peerpad, &req_fmt, &val))) {
        gst_query_set_position (query, req_fmt, val);
        break;
      }

      fmt = GST_FORMAT_TIME;
      if (!(res = gst_pad_query_position (peerpad, &fmt, &pos)))
        break;

      if ((res = gst_pad_query_convert (peerpad, 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_duration (peerpad, &req_fmt, &val))) {
        gst_query_set_duration (query, req_fmt, val);
        break;
      }

      fmt = GST_FORMAT_TIME;
      if (!(res = gst_pad_query_duration (peerpad, &fmt, &dur)))
        break;

      if ((res = gst_pad_query_convert (peerpad, 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_vorbis_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;
    }
    default:
      res = gst_pad_query_default (pad, query);
      break;
  }

error:
  gst_object_unref (peerpad);
  gst_object_unref (vorbisenc);
  return res;
}
Beispiel #29
0
/* 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
xing_mp3_encoder_src_query(GstPad * pad, GstQuery * query)
{
    gboolean res = TRUE;
    XingMp3Encoder *encoder;
    GstPad *peerpad;

    encoder = XING_MP3_ENCODER(gst_pad_get_parent(pad));
    peerpad = gst_pad_get_peer(GST_PAD(encoder->sinkpad));
  
    switch(GST_QUERY_TYPE(query)) {
        case GST_QUERY_DURATION: {
            GstFormat fmt, req_fmt;
            gint64 dur, val;

            gst_query_parse_duration(query, &req_fmt, NULL);
            if((res = gst_pad_query_duration(peerpad, &req_fmt, &val))) {
                gst_query_set_duration(query, req_fmt, val);
                break;
            }

            fmt = GST_FORMAT_TIME;
            if(!(res = gst_pad_query_duration (peerpad, &fmt, &dur))) {
                break;
            }
            
            if((res = gst_pad_query_convert(peerpad, fmt, dur, &req_fmt, &val))) {
                gst_query_set_duration(query, req_fmt, val);
            }
            break;
        }

        case GST_QUERY_POSITION: {
            GstFormat fmt, req_fmt;
            gint64 pos, val;

            gst_query_parse_position(query, &req_fmt, NULL);
            if((res = gst_pad_query_position(peerpad, &req_fmt, &val))) {
                gst_query_set_position (query, req_fmt, val);
                break;
            }

            fmt = GST_FORMAT_TIME;
            if(!(res = gst_pad_query_position(peerpad, &fmt, &pos))) {
                break;
            }
            
            if((res = gst_pad_query_convert(peerpad, fmt, pos, &req_fmt, &val))) {
                gst_query_set_position(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 = xing_mp3_encoder_convert_src(pad, src_fmt, src_val, &dest_fmt, &dest_val))) {
                gst_object_unref(peerpad);
                gst_object_unref(encoder);
            }
            
            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;
}