static gboolean
gst_type_find_handle_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query)
{
  GstTypeFindElement *typefind;
  gboolean res = FALSE;

  typefind = GST_TYPE_FIND_ELEMENT (parent);
  GST_DEBUG_OBJECT (typefind, "Handling src query %s",
      GST_QUERY_TYPE_NAME (query));

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_SCHEDULING:
      /* FIXME, filter out the scheduling modes that we understand */
      res = gst_pad_peer_query (typefind->sink, query);
      break;
    case GST_QUERY_CAPS:
    {
      GST_DEBUG_OBJECT (typefind,
          "Got caps query, our caps are %" GST_PTR_FORMAT, typefind->caps);

      /* We can hijack caps query if we typefind already */
      if (typefind->caps) {
        gst_query_set_caps_result (query, typefind->caps);
        res = TRUE;
      } else {
        res = gst_pad_peer_query (typefind->sink, query);
      }
      break;
    }
    case GST_QUERY_POSITION:
    {
      gint64 peer_pos;
      GstFormat format;

      if (!(res = gst_pad_peer_query (typefind->sink, query)))
        goto out;

      gst_query_parse_position (query, &format, &peer_pos);

      GST_OBJECT_LOCK (typefind);
      /* FIXME: this code assumes that there's no discont in the queue */
      switch (format) {
        case GST_FORMAT_BYTES:
          peer_pos -= gst_adapter_available (typefind->adapter);
          break;
        default:
          /* FIXME */
          break;
      }
      GST_OBJECT_UNLOCK (typefind);
      gst_query_set_position (query, format, peer_pos);
      break;
    }
    default:
      res = gst_pad_query_default (pad, parent, query);
      break;
  }
out:
  return res;
}
/* Probe on the output of a parser chain (the last
 * src pad) */
static GstPadProbeReturn
parse_chain_output_probe (GstPad * pad, GstPadProbeInfo * info,
    DecodebinInputStream * input)
{
  GstPadProbeReturn ret = GST_PAD_PROBE_OK;

  if (GST_IS_EVENT (GST_PAD_PROBE_INFO_DATA (info))) {
    GstEvent *ev = GST_PAD_PROBE_INFO_EVENT (info);

    GST_DEBUG_OBJECT (pad, "Got event %s", GST_EVENT_TYPE_NAME (ev));
    switch (GST_EVENT_TYPE (ev)) {
      case GST_EVENT_STREAM_START:
      {
        GstStream *stream = NULL;
        guint group_id = G_MAXUINT32;
        gst_event_parse_group_id (ev, &group_id);
        GST_DEBUG_OBJECT (pad, "Got stream-start, group_id:%d, input %p",
            group_id, input->input);
        if (set_input_group_id (input->input, &group_id)) {
          ev = gst_event_make_writable (ev);
          gst_event_set_group_id (ev, group_id);
          GST_PAD_PROBE_INFO_DATA (info) = ev;
        }
        input->saw_eos = FALSE;

        gst_event_parse_stream (ev, &stream);
        /* FIXME : Would we ever end up with a stream already set on the input ?? */
        if (stream) {
          if (input->active_stream != stream) {
            MultiQueueSlot *slot;
            if (input->active_stream)
              gst_object_unref (input->active_stream);
            input->active_stream = stream;
            /* We have the beginning of a stream, get a multiqueue slot and link to it */
            g_mutex_lock (&input->dbin->selection_lock);
            slot = get_slot_for_input (input->dbin, input);
            link_input_to_slot (input, slot);
            g_mutex_unlock (&input->dbin->selection_lock);
          } else
            gst_object_unref (stream);
        }
      }
        break;
      case GST_EVENT_CAPS:
      {
        GstCaps *caps = NULL;
        gst_event_parse_caps (ev, &caps);
        GST_DEBUG_OBJECT (pad, "caps %" GST_PTR_FORMAT, caps);
        if (caps && input->active_stream)
          gst_stream_set_caps (input->active_stream, caps);
      }
        break;
      case GST_EVENT_EOS:
        input->saw_eos = TRUE;
        if (all_inputs_are_eos (input->dbin)) {
          GST_DEBUG_OBJECT (pad, "real input pad, marking as EOS");
          check_all_streams_for_eos (input->dbin);
        } else {
          GstPad *peer = gst_pad_get_peer (input->srcpad);
          if (peer) {
            /* Send custom-eos event to multiqueue slot */
            GstStructure *s;
            GstEvent *event;

            GST_DEBUG_OBJECT (pad,
                "Got EOS end of input stream, post custom-eos");
            s = gst_structure_new_empty ("decodebin3-custom-eos");
            event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s);
            gst_pad_send_event (peer, event);
            gst_object_unref (peer);
          } else {
            GST_FIXME_OBJECT (pad, "No peer, what should we do ?");
          }
        }
        ret = GST_PAD_PROBE_DROP;
        break;
      case GST_EVENT_FLUSH_STOP:
        GST_DEBUG_OBJECT (pad, "Clear saw_eos flag");
        input->saw_eos = FALSE;
      default:
        break;
    }
  } else if (GST_IS_QUERY (GST_PAD_PROBE_INFO_DATA (info))) {
    GstQuery *q = GST_PAD_PROBE_INFO_QUERY (info);
    GST_DEBUG_OBJECT (pad, "Seeing query %s", GST_QUERY_TYPE_NAME (q));
    /* If we have a parser, we want to reply to the caps query */
    /* FIXME: Set a flag when the input stream is created for
     * streams where we shouldn't reply to these queries */
    if (GST_QUERY_TYPE (q) == GST_QUERY_CAPS
        && (info->type & GST_PAD_PROBE_TYPE_PULL)) {
      GstCaps *filter = NULL;
      GstCaps *allowed;
      gst_query_parse_caps (q, &filter);
      allowed = get_parser_caps_filter (input->dbin, filter);
      GST_DEBUG_OBJECT (pad,
          "Intercepting caps query, setting %" GST_PTR_FORMAT, allowed);
      gst_query_set_caps_result (q, allowed);
      gst_caps_unref (allowed);
      ret = GST_PAD_PROBE_HANDLED;
    } else if (GST_QUERY_TYPE (q) == GST_QUERY_ACCEPT_CAPS) {
      GstCaps *prop = NULL;
      gst_query_parse_accept_caps (q, &prop);
      /* Fast check against target caps */
      if (gst_caps_can_intersect (prop, input->dbin->caps))
        gst_query_set_accept_caps_result (q, TRUE);
      else {
        gboolean accepted = check_parser_caps_filter (input->dbin, prop);
        /* check against caps filter */
        gst_query_set_accept_caps_result (q, accepted);
        GST_DEBUG_OBJECT (pad, "ACCEPT_CAPS query, returning %d", accepted);
      }
      ret = GST_PAD_PROBE_HANDLED;
    }
  }

  return ret;
}
Beispiel #3
0
QString Query::typeName() const
{
    return QString::fromUtf8(GST_QUERY_TYPE_NAME(object<GstQuery>()));
}
static gboolean
gst_deinterlace2_src_query (GstPad * pad, GstQuery * query)
{
  GstDeinterlace2 *self = GST_DEINTERLACE2 (gst_pad_get_parent (pad));
  gboolean res = FALSE;

  GST_LOG_OBJECT (self, "%s query", GST_QUERY_TYPE_NAME (query));

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_LATENCY:
    {
      GstClockTime min, max;
      gboolean live;
      GstPad *peer;

      if ((peer = gst_pad_get_peer (self->sinkpad))) {
        if ((res = gst_pad_query (peer, query))) {
          GstClockTime latency;
          gint fields_required = 0;
          gint method_latency = 0;

          if (self->method) {
            fields_required =
                gst_deinterlace_method_get_fields_required (self->method);
            method_latency = gst_deinterlace_method_get_latency (self->method);
          }

          gst_query_parse_latency (query, &live, &min, &max);

          GST_DEBUG ("Peer latency: min %"
              GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
              GST_TIME_ARGS (min), GST_TIME_ARGS (max));

          /* add our own latency */
          latency = (fields_required + method_latency) * self->field_duration;

          GST_DEBUG ("Our latency: min %" GST_TIME_FORMAT
              ", max %" GST_TIME_FORMAT,
              GST_TIME_ARGS (latency), GST_TIME_ARGS (latency));

          min += latency;
          if (max != GST_CLOCK_TIME_NONE)
            max += latency;
          else
            max = latency;

          GST_DEBUG ("Calculated total latency : min %"
              GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
              GST_TIME_ARGS (min), GST_TIME_ARGS (max));

          gst_query_set_latency (query, live, min, max);
        }
        gst_object_unref (peer);
      }
      break;
    }
    default:
      res = gst_pad_query_default (pad, query);
      break;
  }

  gst_object_unref (self);
  return res;
}
Beispiel #5
0
static gboolean
gst_spot_src_query (GstBaseSrc * basesrc, GstQuery * query)
{
  gboolean ret = TRUE;
  GstSpotSrc *spot = GST_SPOT_SRC (basesrc);
  gint samplerate = GST_SPOT_SRC_FORMAT (spot)->sample_rate;
  gint64 src_val, dest_val;

  if (!GST_SPOT_SRC_FORMAT (spot)) {
    ret = FALSE;
    goto no_format_yet;
  }

  samplerate = GST_SPOT_SRC_FORMAT (spot)->sample_rate;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
      {
      /*FIXME
       * this one we get, answer it or propagate?
       * seems like if we answer it we are not asked
       * to convert, so i guess this is better? 

      gint64 pos;
      GstFormat format;
      gst_query_parse_position (query, &format, &pos);
      pos = GST_SPOT_SRC_READ_POS (GST_SPOT_SRC (basesrc));
      GST_INFO_OBJECT (spot, "Query_position pos=%"G_GINT64_FORMAT);
       
      */
      ret = FALSE;
      }
      break;

    case GST_QUERY_DURATION:{
      GstFormat format;
      guint64 duration;
      gint64 value;
      gst_query_parse_duration (query, &format, &value);
      /* duration in ms */
      duration = run_spot_cmd (spot, SPOT_CMD_DURATION, 0);
      /* duration in ns */
      duration = 1000000 * duration;
      switch (format) {
        case GST_FORMAT_BYTES:
          {
          guint64 duration_bytes = (duration / 1000000000) * samplerate * 4;
          GST_INFO_OBJECT (spot, "Query_duration, duration_bytes=%" G_GUINT64_FORMAT, duration_bytes);
          gst_query_set_duration (query, format, duration_bytes);
          }
          break;
        case GST_FORMAT_TIME:
          {
          guint64 duration_time = duration;
          GST_INFO_OBJECT (spot, "Query_duration, duration_time=%" G_GUINT64_FORMAT, duration_time);
          gst_query_set_duration (query, format, duration_time);
          }
          break;
        default:
          ret = FALSE;
          g_assert_not_reached ();
          break;
      }
      break;
    }

    /* FIXME: JUST FOR DEBUGING */

    case GST_QUERY_LATENCY:
      /* propagate to basesrc */
      ret = FALSE;
      GST_INFO_OBJECT (spot, "Query_latency");
      break;

    case GST_QUERY_RATE:
      /* propagate to basesrc */
      ret = FALSE;
      GST_INFO_OBJECT (spot, "Query_latency");
      break; 

    case GST_QUERY_SEEKING:
      /* propagate to basesrc */
      ret = FALSE;
      GST_INFO_OBJECT (spot, "Query_seeking");
      break; 

    case GST_QUERY_SEGMENT:
      /* propagate to basesrc */
      ret = FALSE;
      GST_INFO_OBJECT (spot, "Query_segment");
      break; 

    case GST_QUERY_FORMATS:
      /* propagate to basesrc */
      ret = FALSE;
      GST_INFO_OBJECT (spot, "Query_formats");
      break; 

    case GST_QUERY_BUFFERING:
      /* propagate to basesrc */
      ret = FALSE;
      GST_INFO_OBJECT (spot, "Query_buffering");
      break; 

    case GST_QUERY_CONVERT:
      {
        GstFormat src_fmt, dest_fmt;

        gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);

        if (src_fmt == dest_fmt) {
          dest_val = src_val;
          GST_INFO_OBJECT (spot, "Convert done, dst_fmt == src_fmt");
          goto done;
        }

        GST_INFO_OBJECT (spot, "Convert src_fmt=%s to dst_fmt=%s", gst_format_get_name (src_fmt), gst_format_get_name (dest_fmt));

        switch (src_fmt) {
        case GST_FORMAT_BYTES:
          switch (dest_fmt) {
          case GST_FORMAT_TIME:
            /* samples to time convertion 
             *   - each sample has two channels with 16 bits, 4byte
             *   - samplerate is usually 44100hz
             *   - time is in nano seconds */
            dest_val = (src_val * 1000000000) / ((float)samplerate * 4);
            GST_INFO_OBJECT (spot,"Convert src_val=%" G_GINT64_FORMAT " b, dst_val=%" G_GINT64_FORMAT " ns", src_val, dest_val);
            break;
          default:
            ret = FALSE;
            g_assert_not_reached ();
            break;
          }
          break;
        case GST_FORMAT_TIME:
          switch (dest_fmt) {
          case GST_FORMAT_BYTES:
            /* time to samples */
            dest_val = (src_val * samplerate * 4) / 1000000000;
            GST_INFO_OBJECT (spot,"Convert src_val=%" G_GINT64_FORMAT " ns, dst_val=%" G_GINT64_FORMAT " b", src_val, dest_val);
            break;
          default:
            ret = FALSE;
            g_assert_not_reached ();
            break;
          }
          break;
        default:
          ret = FALSE;
          g_assert_not_reached ();
          break;
        }
      done:
        gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
        break;
      }

    case GST_QUERY_URI:
      gst_query_set_uri (query, spot->uri);
    break;

    default:
      GST_LOG_OBJECT (spot, "Query type unknown, default, type=%s", GST_QUERY_TYPE_NAME (query));
      g_assert_not_reached ();
      break;
  }

  if (!ret) {
    GST_LOG_OBJECT (spot, "Let basesrc handle query type=%s", GST_QUERY_TYPE_NAME (query));
    ret = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query);
  }

 no_format_yet:
  if (!ret) {
    GST_DEBUG_OBJECT (spot, "Query failed");
  }

  return ret;
}