예제 #1
0
static gboolean
gst_interleave_src_event (GstPad * pad, GstEvent * event)
{
  GstInterleave *self = GST_INTERLEAVE (gst_pad_get_parent (pad));

  gboolean result;

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

      GstSeekType curtype;

      gint64 cur;

      /* parse the seek parameters */
      gst_event_parse_seek (event, &self->segment_rate, NULL, &flags, &curtype,
          &cur, 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 ());
      }

      /* now wait for the collected to be finished and mark a new
       * segment */
      GST_OBJECT_LOCK (self->collect);
      if (curtype == GST_SEEK_TYPE_SET)
        self->segment_position = cur;
      else
        self->segment_position = 0;
      self->segment_pending = TRUE;
      GST_OBJECT_UNLOCK (self->collect);

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

  return result;
}
예제 #2
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;
}
예제 #3
0
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;
}
예제 #4
0
static gboolean
gst_adder_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstAdder *adder;
  gboolean result;

  adder = GST_ADDER (parent);

  GST_DEBUG_OBJECT (pad, "Got %s event on src pad",
      GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:
    {
      GstSeekFlags flags;
      gdouble rate;
      GstSeekType start_type, stop_type;
      gint64 start, stop;
      GstFormat seek_format, dest_format;
      gboolean flush;

      /* parse the seek parameters */
      gst_event_parse_seek (event, &rate, &seek_format, &flags, &start_type,
          &start, &stop_type, &stop);

      if ((start_type != GST_SEEK_TYPE_NONE)
          && (start_type != GST_SEEK_TYPE_SET)) {
        result = FALSE;
        GST_DEBUG_OBJECT (adder,
            "seeking failed, unhandled seek type for start: %d", start_type);
        goto done;
      }
      if ((stop_type != GST_SEEK_TYPE_NONE) && (stop_type != GST_SEEK_TYPE_SET)) {
        result = FALSE;
        GST_DEBUG_OBJECT (adder,
            "seeking failed, unhandled seek type for end: %d", stop_type);
        goto done;
      }

      dest_format = adder->segment.format;
      if (seek_format != dest_format) {
        result = FALSE;
        GST_DEBUG_OBJECT (adder,
            "seeking failed, unhandled seek format: %d", seek_format);
        goto done;
      }

      flush = (flags & GST_SEEK_FLAG_FLUSH) == GST_SEEK_FLAG_FLUSH;

      /* check if we are flushing */
      if (flush) {
        /* flushing seek, start flush downstream, the flush will be done
         * when all pads received a FLUSH_STOP.
         * Make sure we accept nothing anymore and return WRONG_STATE.
         * We send a flush-start before, to ensure no streaming is done
         * as we need to take the stream lock.
         */
        gst_pad_push_event (adder->srcpad, gst_event_new_flush_start ());
        gst_collect_pads_set_flushing (adder->collect, TRUE);

        /* We can't send FLUSH_STOP here since upstream could start pushing data
         * after we unlock adder->collect.
         * We set flush_stop_pending to TRUE instead and send FLUSH_STOP after
         * forwarding the seek upstream or from gst_adder_collected,
         * whichever happens first.
         */
        GST_COLLECT_PADS_STREAM_LOCK (adder->collect);
        adder->flush_stop_pending = TRUE;
        GST_COLLECT_PADS_STREAM_UNLOCK (adder->collect);
        GST_DEBUG_OBJECT (adder, "mark pending flush stop event");
      }
      GST_DEBUG_OBJECT (adder, "handling seek event: %" GST_PTR_FORMAT, event);

      /* now wait for the collected to be finished and mark a new
       * segment. After we have the lock, no collect function is running and no
       * new collect function will be called for as long as we're flushing. */
      GST_COLLECT_PADS_STREAM_LOCK (adder->collect);
      /* clip position and update our segment */
      if (adder->segment.stop != -1) {
        adder->segment.position = adder->segment.stop;
      }
      gst_segment_do_seek (&adder->segment, rate, seek_format, flags,
          start_type, start, stop_type, stop, NULL);

      if (flush) {
        /* Yes, we need to call _set_flushing again *WHEN* the streaming threads
         * have stopped so that the cookie gets properly updated. */
        gst_collect_pads_set_flushing (adder->collect, TRUE);
      }
      GST_COLLECT_PADS_STREAM_UNLOCK (adder->collect);
      GST_DEBUG_OBJECT (adder, "forwarding seek event: %" GST_PTR_FORMAT,
          event);
      GST_DEBUG_OBJECT (adder, "updated segment: %" GST_SEGMENT_FORMAT,
          &adder->segment);

      /* we're forwarding seek to all upstream peers and wait for one to reply
       * with a newsegment-event before we send a newsegment-event downstream */
      g_atomic_int_set (&adder->new_segment_pending, TRUE);
      result = forward_event (adder, event, flush);
      if (!result) {
        /* seek failed. maybe source is a live source. */
        GST_DEBUG_OBJECT (adder, "seeking failed");
      }
      if (g_atomic_int_compare_and_exchange (&adder->flush_stop_pending,
              TRUE, FALSE)) {
        GST_DEBUG_OBJECT (adder, "pending flush stop");
        if (!gst_pad_push_event (adder->srcpad,
                gst_event_new_flush_stop (TRUE))) {
          GST_WARNING_OBJECT (adder, "Sending flush stop event failed");
        }
      }
      break;
    }
    case GST_EVENT_QOS:
      /* QoS might be tricky */
      result = FALSE;
      gst_event_unref (event);
      break;
    case GST_EVENT_NAVIGATION:
      /* navigation is rather pointless. */
      result = FALSE;
      gst_event_unref (event);
      break;
    default:
      /* just forward the rest for now */
      GST_DEBUG_OBJECT (adder, "forward unhandled event: %s",
          GST_EVENT_TYPE_NAME (event));
      result = forward_event (adder, event, FALSE);
      break;
  }

done:

  return result;
}
예제 #5
0
static gboolean
gst_adder_src_event (GstPad * pad, GstEvent * event)
{
    GstAdder *adder;
    gboolean result;

    adder = GST_ADDER (gst_pad_get_parent (pad));

    switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:
    {
        GstSeekFlags flags;
        GstSeekType curtype, endtype;
        gint64 cur, end;
        gboolean flush;

        /* parse the seek parameters */
        gst_event_parse_seek (event, &adder->segment_rate, NULL, &flags, &curtype,
                              &cur, &endtype, &end);

        if ((curtype != GST_SEEK_TYPE_NONE) && (curtype != GST_SEEK_TYPE_SET)) {
            result = FALSE;
            GST_DEBUG_OBJECT (adder,
                              "seeking failed, unhandled seek type for start: %d", curtype);
            goto done;
        }
        if ((endtype != GST_SEEK_TYPE_NONE) && (endtype != GST_SEEK_TYPE_SET)) {
            result = FALSE;
            GST_DEBUG_OBJECT (adder,
                              "seeking failed, unhandled seek type for end: %d", endtype);
            goto done;
        }

        flush = (flags & GST_SEEK_FLAG_FLUSH) == GST_SEEK_FLAG_FLUSH;

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

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

            /* We can't send FLUSH_STOP here since upstream could start pushing data
             * after we unlock adder->collect.
             * We set flush_stop_pending to TRUE instead and send FLUSH_STOP after
             * forwarding the seek upstream or from gst_adder_collected,
             * whichever happens first.
             */
            adder->flush_stop_pending = TRUE;
        }
        GST_DEBUG_OBJECT (adder, "handling seek event: %" GST_PTR_FORMAT, event);

        /* now wait for the collected to be finished and mark a new
         * segment. After we have the lock, no collect function is running and no
         * new collect function will be called for as long as we're flushing. */
        GST_OBJECT_LOCK (adder->collect);
        if (curtype == GST_SEEK_TYPE_SET)
            adder->segment_start = cur;
        else
            adder->segment_start = 0;
        if (endtype == GST_SEEK_TYPE_SET)
            adder->segment_end = end;
        else
            adder->segment_end = GST_CLOCK_TIME_NONE;
        /* make sure we push a new segment, to inform about new basetime
         * see FIXME in gst_adder_collected() */
        adder->segment_pending = TRUE;
        if (flush) {
            /* Yes, we need to call _set_flushing again *WHEN* the streaming threads
             * have stopped so that the cookie gets properly updated. */
            gst_collect_pads_set_flushing (adder->collect, TRUE);
        }
        GST_OBJECT_UNLOCK (adder->collect);
        GST_DEBUG_OBJECT (adder, "forwarding seek event: %" GST_PTR_FORMAT,
                          event);

        result = forward_event (adder, event, flush);
        if (!result) {
            /* seek failed. maybe source is a live source. */
            GST_DEBUG_OBJECT (adder, "seeking failed");
        }
        if (g_atomic_int_compare_and_exchange (&adder->flush_stop_pending,
                                               TRUE, FALSE)) {
            GST_DEBUG_OBJECT (adder, "pending flush stop");
            gst_pad_push_event (adder->srcpad, gst_event_new_flush_stop ());
        }
        break;
    }
    case GST_EVENT_QOS:
        /* QoS might be tricky */
        result = FALSE;
        break;
    case GST_EVENT_NAVIGATION:
        /* navigation is rather pointless. */
        result = FALSE;
        break;
    default:
        /* just forward the rest for now */
        GST_DEBUG_OBJECT (adder, "forward unhandled event: %s",
                          GST_EVENT_TYPE_NAME (event));
        result = forward_event (adder, event, FALSE);
        break;
    }

done:
    gst_object_unref (adder);

    return result;
}