示例#1
0
static gboolean
gst_adder_sink_event (GstCollectPads2 * pads, GstCollectData2 * pad,
    GstEvent * event, gpointer user_data)
{
  GstAdder *adder = GST_ADDER (user_data);
  gboolean res = FALSE;

  GST_DEBUG_OBJECT (pad->pad, "Got %s event on sink pad from %s",
      GST_EVENT_TYPE_NAME (event), GST_OBJECT_NAME (GST_EVENT_SRC (event)));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_START:
      /* drop flush start events, as we forwarded one already when handing the
       * flushing seek on the sink pad */
      gst_event_unref (event);
      res = TRUE;
      break;
    case GST_EVENT_FLUSH_STOP:
      /* we received a flush-stop. We will only forward it when
       * flush_stop_pending is set, and we will unset it then.
       */
      if (g_atomic_int_compare_and_exchange (&adder->flush_stop_pending,
              TRUE, FALSE)) {
        g_atomic_int_set (&adder->new_segment_pending, TRUE);
        GST_DEBUG_OBJECT (pad->pad, "forwarding flush stop");
      } else {
        gst_event_unref (event);
        res = TRUE;
        GST_DEBUG_OBJECT (pad->pad, "eating flush stop");
      }
      /* Clear pending tags */
      if (adder->pending_events) {
        g_list_foreach (adder->pending_events, (GFunc) gst_event_unref, NULL);
        g_list_free (adder->pending_events);
        adder->pending_events = NULL;
      }
      break;
    case GST_EVENT_TAG:
      /* collect tags here so we can push them out when we collect data */
      adder->pending_events = g_list_append (adder->pending_events, event);
      res = TRUE;
      break;
    case GST_EVENT_NEWSEGMENT:
      if (g_atomic_int_compare_and_exchange (&adder->wait_for_new_segment,
              TRUE, FALSE)) {
        /* make sure we push a new segment, to inform about new basetime
         * see FIXME in gst_adder_collected() */
        g_atomic_int_set (&adder->new_segment_pending, TRUE);
      }
      gst_event_unref (event);
      res = TRUE;
      break;
    default:
      break;
  }
  return res;
}
示例#2
0
static void
gst_event_finalize (GstEvent * event)
{
  g_return_if_fail (event != NULL);
  g_return_if_fail (GST_IS_EVENT (event));

  GST_CAT_LOG (GST_CAT_EVENT, "freeing event %p type %s", event,
      GST_EVENT_TYPE_NAME (event));

  if (GST_EVENT_SRC (event)) {
    gst_object_unref (GST_EVENT_SRC (event));
    GST_EVENT_SRC (event) = NULL;
  }
  if (event->structure) {
    gst_structure_set_parent_refcount (event->structure, NULL);
    gst_structure_free (event->structure);
  }

/*   GST_MINI_OBJECT_CLASS (parent_class)->finalize (GST_MINI_OBJECT (event)); */
}
示例#3
0
static GstEvent *
_gst_event_copy (GstEvent * event)
{
  GstEvent *copy;

  copy = (GstEvent *) gst_mini_object_new (GST_TYPE_EVENT);

  GST_EVENT_TYPE (copy) = GST_EVENT_TYPE (event);
  GST_EVENT_TIMESTAMP (copy) = GST_EVENT_TIMESTAMP (event);
  GST_EVENT_SEQNUM (copy) = GST_EVENT_SEQNUM (event);

  if (GST_EVENT_SRC (event)) {
    GST_EVENT_SRC (copy) = gst_object_ref (GST_EVENT_SRC (event));
  }
  if (event->structure) {
    copy->structure = gst_structure_copy (event->structure);
    gst_structure_set_parent_refcount (copy->structure,
        &copy->mini_object.refcount);
  }
  return copy;
}
示例#4
0
static gboolean
gst_adder_src_event (GstPad * pad, GstEvent * event)
{
  GstAdder *adder;
  gboolean result;

  adder = GST_ADDER (gst_pad_get_parent (pad));

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

  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) {
        /* 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_pads2_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.
         */
        g_atomic_int_set (&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_COLLECT_PADS2_STREAM_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;
      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_pads2_set_flushing (adder->collect, TRUE);
      }
      GST_COLLECT_PADS2_STREAM_UNLOCK (adder->collect);
      GST_DEBUG_OBJECT (adder, "forwarding seek event: %" GST_PTR_FORMAT,
          event);

      /* 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->wait_for_new_segment, 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");
        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;
}