static gboolean
gst_frei0r_mixer_src_query (GstPad * pad, GstObject * object, GstQuery * query)
{
  GstFrei0rMixer *self = GST_FREI0R_MIXER (object);
  gboolean ret = FALSE;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
      ret = gst_pad_query (self->sink0, query);
      break;
    case GST_QUERY_DURATION:
      ret = gst_frei0r_mixer_src_query_duration (self, query);
      break;
    case GST_QUERY_LATENCY:
      ret = gst_frei0r_mixer_src_query_latency (self, query);
      break;
    case GST_QUERY_CAPS:
    {
      GstCaps *filter, *caps;
      gst_query_parse_caps (query, &filter);
      caps = gst_frei0r_mixer_get_caps (self, pad, filter);
      gst_query_set_caps_result (query, caps);
      gst_caps_unref (caps);
      break;
    }
    default:
      ret = gst_pad_query_default (pad, GST_OBJECT (self), query);
      break;
  }

  return ret;
}
Beispiel #2
0
static gboolean
gst_frei0r_mixer_sink0_event (GstPad * pad, GstEvent * event)
{
  GstFrei0rMixer *self = GST_FREI0R_MIXER (gst_pad_get_parent (pad));
  gboolean ret = FALSE;
  GstEvent **p_ev;

  GST_DEBUG ("Got %s event on pad %s:%s", GST_EVENT_TYPE_NAME (event),
      GST_DEBUG_PAD_NAME (pad));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_NEWSEGMENT:
      p_ev = &self->newseg_event;
      gst_event_replace (p_ev, event);
      break;
    default:
      break;
  }

  /* now GstCollectPads can take care of the rest, e.g. EOS */
  ret = self->collect_event (pad, event);

  gst_object_unref (self);

  return ret;
}
Beispiel #3
0
static gboolean
gst_frei0r_mixer_src_query (GstPad * pad, GstQuery * query)
{
  GstFrei0rMixer *self = GST_FREI0R_MIXER (gst_pad_get_parent (pad));
  gboolean ret = FALSE;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
      ret = gst_pad_query (self->sink0, query);
      break;
    case GST_QUERY_DURATION:
      ret = gst_frei0r_mixer_src_query_duration (self, query);
      break;
    case GST_QUERY_LATENCY:
      ret = gst_frei0r_mixer_src_query_latency (self, query);
      break;
    default:
      ret = gst_pad_query_default (pad, query);
      break;
  }

  gst_object_unref (self);

  return ret;
}
Beispiel #4
0
static gboolean
gst_frei0r_mixer_set_caps (GstPad * pad, GstCaps * caps)
{
  GstFrei0rMixer *self = GST_FREI0R_MIXER (gst_pad_get_parent (pad));
  gboolean ret = TRUE;

  gst_caps_replace (&self->caps, caps);

  if (pad != self->src)
    ret &= gst_pad_set_caps (self->src, caps);
  if (pad != self->sink0)
    ret &= gst_pad_set_caps (self->sink0, caps);
  if (pad != self->sink1)
    ret &= gst_pad_set_caps (self->sink1, caps);
  if (pad != self->sink2 && self->sink2)
    ret &= gst_pad_set_caps (self->sink2, caps);

  if (ret) {
    if (!gst_video_format_parse_caps (caps, &self->fmt, &self->width,
            &self->height)) {
      ret = FALSE;
      goto out;
    }
  }
out:

  gst_object_unref (self);

  return ret;
}
Beispiel #5
0
static gboolean
gst_frei0r_mixer_sink_query (GstPad * pad, GstQuery * query)
{
  GstFrei0rMixer *self = GST_FREI0R_MIXER (gst_pad_get_parent (pad));
  gboolean ret = gst_pad_query (self->src, query);

  gst_object_unref (self);

  return ret;
}
Beispiel #6
0
static GstCaps *
gst_frei0r_mixer_get_caps (GstPad * pad)
{
  GstFrei0rMixer *self = GST_FREI0R_MIXER (gst_pad_get_parent (pad));
  GstCaps *caps = NULL;

  if (self->caps) {
    caps = gst_caps_ref (self->caps);
  } else {
    GstCaps *tmp, *tmp1;

    tmp = gst_caps_copy (gst_pad_get_pad_template_caps (self->src));
    tmp1 = gst_pad_peer_get_caps (pad);
    if (tmp1) {
      caps = gst_caps_intersect (tmp, tmp1);
      gst_caps_unref (tmp1);
      gst_caps_unref (tmp);
    } else {
      caps = tmp;
    }

    tmp = caps;
    tmp1 = gst_pad_peer_get_caps (self->sink0);
    if (tmp1) {
      caps = gst_caps_intersect (tmp, tmp1);
      gst_caps_unref (tmp);
      gst_caps_unref (tmp1);
    }

    tmp = caps;
    tmp1 = gst_pad_peer_get_caps (self->sink1);
    if (tmp1) {
      caps = gst_caps_intersect (tmp, tmp1);
      gst_caps_unref (tmp);
      gst_caps_unref (tmp1);
    }

    if (self->sink2) {
      tmp = caps;
      tmp1 = gst_pad_peer_get_caps (self->sink2);
      if (tmp1) {
        caps = gst_caps_intersect (tmp, tmp1);
        gst_caps_unref (tmp);
        gst_caps_unref (tmp1);
      }
    }
  }

  gst_object_unref (self);

  return caps;
}
static void
gst_frei0r_mixer_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstFrei0rMixer *self = GST_FREI0R_MIXER (object);
  GstFrei0rMixerClass *klass = GST_FREI0R_MIXER_GET_CLASS (object);

  GST_OBJECT_LOCK (self);
  if (!gst_frei0r_set_property (self->f0r_instance, klass->ftable,
          klass->properties, klass->n_properties, self->property_cache, prop_id,
          value))
    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  GST_OBJECT_UNLOCK (self);
}
static void
gst_frei0r_mixer_finalize (GObject * object)
{
  GstFrei0rMixer *self = GST_FREI0R_MIXER (object);
  GstFrei0rMixerClass *klass = GST_FREI0R_MIXER_GET_CLASS (object);

  if (self->property_cache)
    gst_frei0r_property_cache_free (klass->properties, self->property_cache,
        klass->n_properties);
  self->property_cache = NULL;

  if (self->collect)
    gst_object_unref (self->collect);
  self->collect = NULL;

  G_OBJECT_CLASS (g_type_class_peek_parent (klass))->finalize (object);
}
Beispiel #9
0
static gboolean
gst_frei0r_mixer_src_event (GstPad * pad, GstEvent * event)
{
  GstFrei0rMixer *self = GST_FREI0R_MIXER (gst_pad_get_parent (pad));
  gboolean ret = FALSE;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_QOS:
      /* QoS might be tricky */
      ret = FALSE;
      break;
    case GST_EVENT_SEEK:
    {
      GstSeekFlags flags;

      /* parse the seek parameters */
      gst_event_parse_seek (event, NULL, NULL, &flags, NULL, NULL, NULL, NULL);

      /* check if we are flushing */
      if (flags & GST_SEEK_FLAG_FLUSH) {
        /* make sure we accept nothing anymore and return WRONG_STATE */
        gst_collect_pads_set_flushing (self->collect, TRUE);

        /* flushing seek, start flush downstream, the flush will be done
         * when all pads received a FLUSH_STOP. */
        gst_pad_push_event (self->src, gst_event_new_flush_start ());
      }

      ret = forward_event (self, event);
      break;
    }
    case GST_EVENT_NAVIGATION:
      /* navigation is rather pointless. */
      ret = FALSE;
      break;
    default:
      /* just forward the rest for now */
      ret = forward_event (self, event);
      break;
  }

  gst_object_unref (self);

  return ret;
}
static GstStateChangeReturn
gst_frei0r_mixer_change_state (GstElement * element, GstStateChange transition)
{
  GstFrei0rMixer *self = GST_FREI0R_MIXER (element);
  GstFrei0rMixerClass *klass = GST_FREI0R_MIXER_GET_CLASS (self);
  GstStateChangeReturn ret;

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      gst_collect_pads_start (self->collect);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      break;
    default:
      break;
  }

  /* Stop before calling the parent's state change function as
   * GstCollectPads might take locks and we would deadlock in that
   * case
   */
  if (transition == GST_STATE_CHANGE_PAUSED_TO_READY)
    gst_collect_pads_stop (self->collect);

  ret =
      GST_ELEMENT_CLASS (g_type_class_peek_parent (klass))->change_state
      (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_frei0r_mixer_reset (self);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      break;
    default:
      break;
  }

  return ret;
}
static gboolean
gst_frei0r_mixer_src_event (GstPad * pad, GstObject * object, GstEvent * event)
{
  GstFrei0rMixer *self = GST_FREI0R_MIXER (object);
  gboolean ret = FALSE;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_QOS:
      /* QoS might be tricky */
      ret = FALSE;
      break;
    case GST_EVENT_SEEK:
    {
      GstSeekFlags flags;

      /* parse the seek parameters */
      gst_event_parse_seek (event, NULL, NULL, &flags, NULL, NULL, NULL, NULL);

      /* check if we are flushing */
      if (flags & GST_SEEK_FLAG_FLUSH) {
        /* make sure we accept nothing anymore and return WRONG_STATE */
        gst_collect_pads_set_flushing (self->collect, TRUE);

        /* flushing seek, start flush downstream, the flush will be done
         * when all pads received a FLUSH_STOP. */
        gst_pad_push_event (self->src, gst_event_new_flush_start ());
      }

      ret = gst_pad_event_default (pad, GST_OBJECT (self), event);
      break;
    }
    default:
      ret = gst_pad_event_default (pad, GST_OBJECT (self), event);
      break;
  }

  return ret;
}