コード例 #1
0
ファイル: gstevent.c プロジェクト: Grobik1/gstreamer
/**
 * gst_event_new_custom:
 * @type: The type of the new event
 * @structure: (transfer full): the structure for the event. The event will
 *     take ownership of the structure.
 *
 * Create a new custom-typed event. This can be used for anything not
 * handled by other event-specific functions to pass an event to another
 * element.
 *
 * Make sure to allocate an event type with the #GST_EVENT_MAKE_TYPE macro,
 * assigning a free number and filling in the correct direction and
 * serialization flags.
 *
 * New custom events can also be created by subclassing the event type if
 * needed.
 *
 * Returns: (transfer full): the new custom event.
 */
GstEvent *
gst_event_new_custom (GstEventType type, GstStructure * structure)
{
  GstEventImpl *event;

  event = g_slice_new0 (GstEventImpl);

  GST_CAT_DEBUG (GST_CAT_EVENT, "creating new event %p %s %d", event,
      gst_event_type_get_name (type), type);

  if (structure) {
    /* structure must not have a parent */
    if (!gst_structure_set_parent_refcount (structure,
            &event->event.mini_object.refcount))
      goto had_parent;

  }
  gst_event_init (event, type);

  GST_EVENT_STRUCTURE (event) = structure;

  return GST_EVENT_CAST (event);

  /* ERRORS */
had_parent:
  {
    g_slice_free1 (sizeof (GstEventImpl), event);
    g_warning ("structure is already owned by another object");
    return NULL;
  }
}
コード例 #2
0
static gboolean
gst_fake_src_event_handler (GstBaseSrc * basesrc, GstEvent * event)
{
  GstFakeSrc *src;

  src = GST_FAKE_SRC (basesrc);

  if (!src->silent) {
    const GstStructure *s;
    const gchar *tstr;
    gchar *sstr;

    GST_OBJECT_LOCK (src);
    g_free (src->last_message);

    tstr = gst_event_type_get_name (GST_EVENT_TYPE (event));

    if ((s = gst_event_get_structure (event)))
      sstr = gst_structure_to_string (s);
    else
      sstr = g_strdup ("");

    src->last_message =
        g_strdup_printf ("event   ******* (%s:%s) E (type: %s (%d), %s) %p",
        GST_DEBUG_PAD_NAME (GST_BASE_SRC_CAST (src)->srcpad),
        tstr, GST_EVENT_TYPE (event), sstr, event);
    g_free (sstr);
    GST_OBJECT_UNLOCK (src);

    g_object_notify_by_pspec ((GObject *) src, pspec_last_message);
  }

  return GST_BASE_SRC_CLASS (parent_class)->event (basesrc, event);
}
コード例 #3
0
ファイル: mpf-test-eos.c プロジェクト: mdqyy/AMPF
static gboolean pad_event_handler(GstPad *pad, GstEvent *event) {
	// Establish thread-local.
	MpfComponent *component = MPF_COMPONENT(GST_OBJECT_PARENT(pad));
	mpf_component_set_curcomponent(component);
	GstElement *element = gst_pad_get_parent_element(pad);

	gchar *elementname = gst_element_get_name(element);
	gchar *padname = gst_pad_get_name(pad);
	const gchar *eventname = gst_event_type_get_name(event->type);

	MPF_PRIVATE_ALWAYS("element=%s pad=%s event=%s\n", elementname, padname,
			eventname);
	// If EOS, poke a message out of the events pad.
	if (event->type == GST_EVENT_EOS) {
		GstPad *events = gst_element_get_pad(element, "events");

		printf("GstPad *events=%p\n", events);

		GString *string = g_string_new("");
		g_string_printf(string, "%s: EOS buffer_count=%d\n", elementname,
				mpf_private.buffer_count);
		mpf_voidstar_push("events", mpf_voidstar_stralloc(string->str));
		mpf_voidstar_send_outbuffers();
		gst_pad_push_event(events, gst_event_new_eos());
	}

	g_free(elementname);
	g_free(padname);
	return gst_pad_event_default(pad, event);
}
コード例 #4
0
ファイル: kmselement.c プロジェクト: shelsonjava/kms-core
static GstPadProbeReturn
accept_eos_probe (GstPad * pad, GstPadProbeInfo * info, gpointer data)
{
  GstEvent *event = gst_pad_probe_info_get_event (info);
  GstEventType type = GST_EVENT_TYPE (event);

  if (type == GST_EVENT_EOS || type == GST_EVENT_FLUSH_START
      || type == GST_EVENT_FLUSH_STOP) {
    KmsElement *self;
    gboolean accept;

    self = KMS_ELEMENT (data);
    KMS_ELEMENT_LOCK (self);
    accept = self->priv->accept_eos;
    KMS_ELEMENT_UNLOCK (self);

    if (!accept) {
      GST_DEBUG_OBJECT (pad, "Event %s dropped",
          gst_event_type_get_name (type));
    }

    return (accept) ? GST_PAD_PROBE_OK : GST_PAD_PROBE_DROP;
  }

  return GST_PAD_PROBE_OK;
}
コード例 #5
0
ファイル: queue.c プロジェクト: AlerIl/gstreamer0.10
static gboolean
event_func (GstPad * pad, GstEvent * event)
{
  GST_DEBUG ("%s event", gst_event_type_get_name (GST_EVENT_TYPE (event)));
  events = g_list_append (events, event);

  return TRUE;
}
コード例 #6
0
ファイル: testegl.c プロジェクト: ryumiel/gst-omx
static gboolean
handle_queued_objects (APP_STATE_T * state)
{
    GstMiniObject *object = NULL;

    g_mutex_lock (&state->queue_lock);
    if (state->flushing) {
        g_cond_broadcast (&state->cond);
        goto beach;
    } else if (g_async_queue_length (state->queue) == 0) {
        goto beach;
    }

    if ((object = g_async_queue_try_pop (state->queue))) {
        if (GST_IS_BUFFER (object)) {
            GstBuffer *buffer = GST_BUFFER_CAST (object);
            update_image (state, buffer);
            render_scene (state);
            gst_buffer_unref (buffer);
            if (!SYNC_BUFFERS) {
                object = NULL;
            }
        } else if (GST_IS_QUERY (object)) {
            GstQuery *query = GST_QUERY_CAST (object);
            GstStructure *s = (GstStructure *) gst_query_get_structure (query);

            if (gst_structure_has_name (s, "not-used")) {
                g_assert_not_reached ();
            } else {
                g_assert_not_reached ();
            }
        } else if (GST_IS_EVENT (object)) {
            GstEvent *event = GST_EVENT_CAST (object);
            g_print ("\nevent %p %s\n", event,
                     gst_event_type_get_name (GST_EVENT_TYPE (event)));

            switch (GST_EVENT_TYPE (event)) {
            case GST_EVENT_EOS:
                flush_internal (state);
                break;
            default:
                break;
            }
            gst_event_unref (event);
            object = NULL;
        }
    }

    if (object) {
        state->popped_obj = object;
        g_cond_broadcast (&state->cond);
    }

beach:
    g_mutex_unlock (&state->queue_lock);

    return FALSE;
}
コード例 #7
0
ファイル: mpegtsbase.c プロジェクト: Lachann/gst-plugins-bad
static gboolean
mpegts_base_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res = TRUE;
  gboolean hard;
  MpegTSBase *base = GST_MPEGTS_BASE (parent);

  GST_DEBUG_OBJECT (base, "Got event %s",
      gst_event_type_get_name (GST_EVENT_TYPE (event)));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
      gst_event_copy_segment (event, &base->segment);
      GST_DEBUG_OBJECT (base, "Received segment %" GST_SEGMENT_FORMAT,
          &base->segment);
      /* Check if we need to switch PCR/PTS handling */
      if (base->segment.format == GST_FORMAT_TIME) {
        base->packetizer->calculate_offset = FALSE;
        base->packetizer->calculate_skew = TRUE;
      } else {
        base->packetizer->calculate_offset = TRUE;
        base->packetizer->calculate_skew = FALSE;
      }
      res = GST_MPEGTS_BASE_GET_CLASS (base)->push_event (base, event);
      break;
    case GST_EVENT_STREAM_START:
      gst_event_unref (event);
      break;
    case GST_EVENT_EOS:
      res = GST_MPEGTS_BASE_GET_CLASS (base)->push_event (base, event);
      res = gst_mpegts_base_handle_eos (base);
      break;
    case GST_EVENT_CAPS:
      /* FIXME, do something */
      gst_event_unref (event);
      break;
    case GST_EVENT_FLUSH_STOP:
      res = GST_MPEGTS_BASE_GET_CLASS (base)->push_event (base, event);
      hard = (base->mode != BASE_MODE_SEEKING);
      mpegts_packetizer_flush (base->packetizer, hard);
      mpegts_base_flush (base, hard);
      gst_segment_init (&base->segment, GST_FORMAT_UNDEFINED);
      base->seen_pat = FALSE;
      break;
    default:
      res = GST_MPEGTS_BASE_GET_CLASS (base)->push_event (base, event);
  }

  /* Always return TRUE for sticky events */
  if (GST_EVENT_IS_STICKY (event))
    res = TRUE;

  return res;
}
コード例 #8
0
static gboolean
gst_fake_sink_event (GstBaseSink * bsink, GstEvent * event)
{
  GstFakeSink *sink = GST_FAKE_SINK (bsink);

  if (!sink->silent) {
    const GstStructure *s;
    const gchar *tstr;
    gchar *sstr;

    GST_OBJECT_LOCK (sink);
    g_free (sink->last_message);

    if (GST_EVENT_TYPE (event) == GST_EVENT_SINK_MESSAGE) {
      GstMessage *msg;
      const GstStructure *structure;

      gst_event_parse_sink_message (event, &msg);
      structure = gst_message_get_structure (msg);
      sstr = gst_structure_to_string (structure);
      sink->last_message =
          g_strdup_printf ("message ******* (%s:%s) M (type: %d, %s) %p",
          GST_DEBUG_PAD_NAME (GST_BASE_SINK_CAST (sink)->sinkpad),
          GST_MESSAGE_TYPE (msg), sstr, msg);
      gst_message_unref (msg);
    } else {
      tstr = gst_event_type_get_name (GST_EVENT_TYPE (event));

      if ((s = gst_event_get_structure (event))) {
        sstr = gst_structure_to_string (s);
      } else {
        sstr = g_strdup ("");
      }

      sink->last_message =
          g_strdup_printf ("event   ******* (%s:%s) E (type: %s (%d), %s) %p",
          GST_DEBUG_PAD_NAME (GST_BASE_SINK_CAST (sink)->sinkpad),
          tstr, GST_EVENT_TYPE (event), sstr, event);
    }
    g_free (sstr);
    GST_OBJECT_UNLOCK (sink);

    gst_fake_sink_notify_last_message (sink);
  }

  return GST_BASE_SINK_CLASS (parent_class)->event (bsink, event);
}
コード例 #9
0
ファイル: gstevent.c プロジェクト: JERUKA9/gstreamer
static GstEvent *
gst_event_new (GstEventType type)
{
  GstEvent *event;

  event = (GstEvent *) gst_mini_object_new (GST_TYPE_EVENT);

  GST_CAT_DEBUG (GST_CAT_EVENT, "creating new event %p %s %d", event,
      gst_event_type_get_name (type), type);

  event->type = type;
  event->src = NULL;
  event->structure = NULL;
  GST_EVENT_SEQNUM (event) = gst_util_seqnum_next ();

  return event;
}
コード例 #10
0
ファイル: gstteletextdec.c プロジェクト: pli3/gst-plugins-bad
static gboolean
gst_teletextdec_sink_event (GstPad * pad, GstEvent * event)
{
  gboolean ret;
  GstTeletextDec *teletext = GST_TELETEXTDEC (gst_pad_get_parent (pad));

  GST_DEBUG_OBJECT (teletext, "got event %s",
      gst_event_type_get_name (GST_EVENT_TYPE (event)));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_NEWSEGMENT:
      /* maybe save and/or update the current segment (e.g. for output
       * clipping) or convert the event into one in a different format
       * (e.g. BYTES to TIME) or drop it and set a flag to send a newsegment
       * event in a different format later */
      ret = gst_pad_push_event (teletext->srcpad, event);
      break;
    case GST_EVENT_EOS:
      /* end-of-stream, we should close down all stream leftovers here */
      gst_teletextdec_zvbi_clear (teletext);
      ret = gst_pad_push_event (teletext->srcpad, event);
      break;
    case GST_EVENT_FLUSH_STOP:
      gst_teletextdec_zvbi_clear (teletext);
      gst_teletextdec_zvbi_init (teletext);
      ret = gst_pad_push_event (teletext->srcpad, event);
      break;
    default:
      ret = gst_pad_event_default (pad, event);
      break;
  }

  gst_object_unref (teletext);

  return ret;
}
コード例 #11
0
ファイル: gstidentity.c プロジェクト: PeterXu/gst-mobile
static gboolean
gst_identity_sink_event (GstBaseTransform * trans, GstEvent * event)
{
  GstIdentity *identity;
  gboolean ret = TRUE;

  identity = GST_IDENTITY (trans);

  if (!identity->silent) {
    const GstStructure *s;
    const gchar *tstr;
    gchar *sstr;

    GST_OBJECT_LOCK (identity);
    g_free (identity->last_message);

    tstr = gst_event_type_get_name (GST_EVENT_TYPE (event));
    if ((s = gst_event_get_structure (event)))
      sstr = gst_structure_to_string (s);
    else
      sstr = g_strdup ("");

    identity->last_message =
        g_strdup_printf ("event   ******* (%s:%s) E (type: %s (%d), %s) %p",
        GST_DEBUG_PAD_NAME (trans->sinkpad), tstr, GST_EVENT_TYPE (event),
        sstr, event);
    g_free (sstr);
    GST_OBJECT_UNLOCK (identity);

    gst_identity_notify_last_message (identity);
  }

  if (identity->single_segment && (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT)) {
    if (trans->have_segment == FALSE) {
      GstEvent *news;
      GstSegment segment;

      gst_event_copy_segment (event, &segment);
      gst_event_copy_segment (event, &trans->segment);
      trans->have_segment = TRUE;

      /* This is the first segment, send out a (0, -1) segment */
      gst_segment_init (&segment, segment.format);
      news = gst_event_new_segment (&segment);

      gst_pad_event_default (trans->sinkpad, GST_OBJECT_CAST (trans), news);
    }
  }

  /* Reset previous timestamp, duration and offsets on NEWSEGMENT
   * to prevent false warnings when checking for perfect streams */
  if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
    identity->prev_timestamp = identity->prev_duration = GST_CLOCK_TIME_NONE;
    identity->prev_offset = identity->prev_offset_end = GST_BUFFER_OFFSET_NONE;
  }

  if (identity->single_segment && GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
    /* eat up segments */
    gst_event_unref (event);
    ret = TRUE;
  } else {
    if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_START) {
      GST_OBJECT_LOCK (identity);
      if (identity->clock_id) {
        GST_DEBUG_OBJECT (identity, "unlock clock wait");
        gst_clock_id_unschedule (identity->clock_id);
        gst_clock_id_unref (identity->clock_id);
        identity->clock_id = NULL;
      }
      GST_OBJECT_UNLOCK (identity);
    }

    ret = GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event);
  }

  return ret;
}
コード例 #12
0
ファイル: testegl.c プロジェクト: 01org/gst-omx
static gboolean
handle_queued_objects (APP_STATE_T * state)
{
  GstMiniObject *object = NULL;

  g_mutex_lock (state->queue_lock);
  if (state->flushing) {
    g_cond_broadcast (state->cond);
    goto beach;
  } else if (g_async_queue_length (state->queue) == 0) {
    goto beach;
  }

  if ((object = g_async_queue_try_pop (state->queue))) {
    if (GST_IS_BUFFER (object)) {
      GstBuffer *buffer = GST_BUFFER_CAST (object);
      update_image (state, buffer);
      render_scene (state);
      gst_buffer_unref (buffer);
      if (!SYNC_BUFFERS) {
        object = NULL;
      }
    } else if (GST_IS_QUERY (object)) {
      GstQuery *query = GST_QUERY_CAST (object);
      GstStructure *s = (GstStructure *) gst_query_get_structure (query);

      if (gst_structure_has_name (s, "eglglessink-allocate-eglimage")) {
        GstBuffer *buffer;
        GstVideoFormat format;
        gint width, height;
        GValue v = { 0, };

        if (!gst_structure_get_enum (s, "format", GST_TYPE_VIDEO_FORMAT,
                (gint *) & format)
            || !gst_structure_get_int (s, "width", &width)
            || !gst_structure_get_int (s, "height", &height)) {
          g_assert_not_reached ();
        }

        buffer =
            gst_egl_allocate_eglimage (state,
            GST_EGL_IMAGE_BUFFER_POOL (state->pool)->allocator, format,
            width, height);
        g_value_init (&v, G_TYPE_POINTER);
        g_value_set_pointer (&v, buffer);

        gst_structure_set_value (s, "buffer", &v);
        g_value_unset (&v);
      } else {
        g_assert_not_reached ();
      }
    } else if (GST_IS_EVENT (object)) {
      GstEvent *event = GST_EVENT_CAST (object);
      g_print ("\nevent %p %s\n", event,
          gst_event_type_get_name (GST_EVENT_TYPE (event)));

      switch (GST_EVENT_TYPE (event)) {
        case GST_EVENT_EOS:
          flush_internal (state);
          break;
        default:
          break;
      }
      gst_event_unref (event);
      object = NULL;
    }
  }

  if (object) {
    state->popped_obj = object;
    g_cond_broadcast (state->cond);
  }

beach:
  g_mutex_unlock (state->queue_lock);

  return FALSE;
}
コード例 #13
0
static GstFlowReturn
gst_gdp_depay_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  GstGDPDepay *this;
  GstFlowReturn ret = GST_FLOW_OK;
  GstCaps *caps;
  GstBuffer *buf;
  GstEvent *event;
  guint available;

  this = GST_GDP_DEPAY (parent);

  /* On DISCONT, get rid of accumulated data. We assume a buffer after the
   * DISCONT contains (part of) a new valid header, if not we error because we
   * lost sync */
  if (GST_BUFFER_IS_DISCONT (buffer)) {
    gst_adapter_clear (this->adapter);
    this->state = GST_GDP_DEPAY_STATE_HEADER;
  }
  gst_adapter_push (this->adapter, buffer);

  while (TRUE) {
    switch (this->state) {
      case GST_GDP_DEPAY_STATE_HEADER:
      {
        guint8 *header;

        /* collect a complete header, validate and store the header. Figure out
         * the payload length and switch to the PAYLOAD state */
        available = gst_adapter_available (this->adapter);
        if (available < GST_DP_HEADER_LENGTH)
          goto done;

        GST_LOG_OBJECT (this, "reading GDP header from adapter");
        header = gst_adapter_take (this->adapter, GST_DP_HEADER_LENGTH);
        if (!gst_dp_validate_header (GST_DP_HEADER_LENGTH, header)) {
          g_free (header);
          goto header_validate_error;
        }

        /* store types and payload length. Also store the header, which we need
         * to make the payload. */
        this->payload_length = gst_dp_header_payload_length (header);
        this->payload_type = gst_dp_header_payload_type (header);
        /* free previous header and store new one. */
        g_free (this->header);
        this->header = header;

        GST_LOG_OBJECT (this,
            "read GDP header, payload size %d, payload type %d, switching to state PAYLOAD",
            this->payload_length, this->payload_type);
        this->state = GST_GDP_DEPAY_STATE_PAYLOAD;
        break;
      }
      case GST_GDP_DEPAY_STATE_PAYLOAD:
      {
        /* in this state we wait for all the payload data to be available in the
         * adapter. Then we switch to the state where we actually process the
         * payload. */
        available = gst_adapter_available (this->adapter);
        if (available < this->payload_length)
          goto done;

        /* change state based on type */
        if (this->payload_type == GST_DP_PAYLOAD_BUFFER) {
          GST_LOG_OBJECT (this, "switching to state BUFFER");
          this->state = GST_GDP_DEPAY_STATE_BUFFER;
        } else if (this->payload_type == GST_DP_PAYLOAD_CAPS) {
          GST_LOG_OBJECT (this, "switching to state CAPS");
          this->state = GST_GDP_DEPAY_STATE_CAPS;
        } else if (this->payload_type >= GST_DP_PAYLOAD_EVENT_NONE) {
          GST_LOG_OBJECT (this, "switching to state EVENT");
          this->state = GST_GDP_DEPAY_STATE_EVENT;
        } else {
          goto wrong_type;
        }

        if (this->payload_length) {
          const guint8 *data;
          gboolean res;

          data = gst_adapter_map (this->adapter, this->payload_length);
          res = gst_dp_validate_payload (GST_DP_HEADER_LENGTH, this->header,
              data);
          gst_adapter_unmap (this->adapter);

          if (!res)
            goto payload_validate_error;
        }

        break;
      }
      case GST_GDP_DEPAY_STATE_BUFFER:
      {
        /* if we receive a buffer without caps first, we error out */
        if (!this->caps)
          goto no_caps;

        GST_LOG_OBJECT (this, "reading GDP buffer from adapter");
        buf = gst_dp_buffer_from_header (GST_DP_HEADER_LENGTH, this->header);
        if (!buf)
          goto buffer_failed;

        /* now take the payload if there is any */
        if (this->payload_length > 0) {
          GstMapInfo map;

          gst_buffer_map (buf, &map, GST_MAP_WRITE);
          gst_adapter_copy (this->adapter, map.data, 0, this->payload_length);
          gst_buffer_unmap (buf, &map);

          gst_adapter_flush (this->adapter, this->payload_length);
        }

        /* set caps and push */
        GST_LOG_OBJECT (this, "deserialized buffer %p, pushing, timestamp %"
            GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT
            ", offset %" G_GINT64_FORMAT ", offset_end %" G_GINT64_FORMAT
            ", size %" G_GSIZE_FORMAT ", flags 0x%x",
            buf,
            GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
            GST_TIME_ARGS (GST_BUFFER_DURATION (buf)),
            GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf),
            gst_buffer_get_size (buf), GST_BUFFER_FLAGS (buf));
        ret = gst_pad_push (this->srcpad, buf);
        if (ret != GST_FLOW_OK)
          goto push_error;

        GST_LOG_OBJECT (this, "switching to state HEADER");
        this->state = GST_GDP_DEPAY_STATE_HEADER;
        break;
      }
      case GST_GDP_DEPAY_STATE_CAPS:
      {
        guint8 *payload;

        /* take the payload of the caps */
        GST_LOG_OBJECT (this, "reading GDP caps from adapter");
        payload = gst_adapter_take (this->adapter, this->payload_length);
        caps = gst_dp_caps_from_packet (GST_DP_HEADER_LENGTH, this->header,
            payload);
        g_free (payload);
        if (!caps)
          goto caps_failed;

        GST_DEBUG_OBJECT (this, "deserialized caps %" GST_PTR_FORMAT, caps);
        gst_caps_replace (&(this->caps), caps);
        gst_pad_set_caps (this->srcpad, caps);
        /* drop the creation ref we still have */
        gst_caps_unref (caps);

        GST_LOG_OBJECT (this, "switching to state HEADER");
        this->state = GST_GDP_DEPAY_STATE_HEADER;
        break;
      }
      case GST_GDP_DEPAY_STATE_EVENT:
      {
        guint8 *payload;

        GST_LOG_OBJECT (this, "reading GDP event from adapter");

        /* adapter doesn't like 0 length payload */
        if (this->payload_length > 0)
          payload = gst_adapter_take (this->adapter, this->payload_length);
        else
          payload = NULL;
        event = gst_dp_event_from_packet (GST_DP_HEADER_LENGTH, this->header,
            payload);
        g_free (payload);
        if (!event)
          goto event_failed;

        GST_DEBUG_OBJECT (this, "deserialized event %p of type %s, pushing",
            event, gst_event_type_get_name (event->type));
        gst_pad_push_event (this->srcpad, event);

        GST_LOG_OBJECT (this, "switching to state HEADER");
        this->state = GST_GDP_DEPAY_STATE_HEADER;
        break;
      }
    }
  }

done:
  return ret;

  /* ERRORS */
header_validate_error:
  {
    GST_ELEMENT_ERROR (this, STREAM, DECODE, (NULL),
        ("GDP packet header does not validate"));
    ret = GST_FLOW_ERROR;
    goto done;
  }
payload_validate_error:
  {
    GST_ELEMENT_ERROR (this, STREAM, DECODE, (NULL),
        ("GDP packet payload does not validate"));
    ret = GST_FLOW_ERROR;
    goto done;
  }
wrong_type:
  {
    GST_ELEMENT_ERROR (this, STREAM, DECODE, (NULL),
        ("GDP packet header is of wrong type"));
    ret = GST_FLOW_ERROR;
    goto done;
  }
no_caps:
  {
    GST_ELEMENT_ERROR (this, STREAM, DECODE, (NULL),
        ("Received a buffer without first receiving caps"));
    ret = GST_FLOW_NOT_NEGOTIATED;
    goto done;
  }
buffer_failed:
  {
    GST_ELEMENT_ERROR (this, STREAM, DECODE, (NULL),
        ("could not create buffer from GDP packet"));
    ret = GST_FLOW_ERROR;
    goto done;
  }
push_error:
  {
    GST_WARNING_OBJECT (this, "pushing depayloaded buffer returned %d", ret);
    goto done;
  }
caps_failed:
  {
    GST_ELEMENT_ERROR (this, STREAM, DECODE, (NULL),
        ("could not create caps from GDP packet"));
    ret = GST_FLOW_ERROR;
    goto done;
  }
event_failed:
  {
    GST_ELEMENT_ERROR (this, STREAM, DECODE, (NULL),
        ("could not create event from GDP packet"));
    ret = GST_FLOW_ERROR;
    goto done;
  }
}
コード例 #14
0
static gboolean gst_dvbvideosink_event(GstBaseSink *sink, GstEvent *event)
{
	GstDVBVideoSink *self = GST_DVBVIDEOSINK (sink);
	GST_DEBUG_OBJECT (self, "EVENT %s", gst_event_type_get_name(GST_EVENT_TYPE (event)));
	int ret = TRUE;

	switch (GST_EVENT_TYPE (event))
	{
	case GST_EVENT_FLUSH_START:
		self->flushing = TRUE;
		/* wakeup the poll */
		write(self->unlockfd[1], "\x01", 1);
		break;
	case GST_EVENT_FLUSH_STOP:
		if (self->fd >= 0) ioctl(self->fd, VIDEO_CLEAR_BUFFER);
		GST_OBJECT_LOCK(self);
		self->must_send_header = TRUE;
		while (self->queue)
		{
			queue_pop(&self->queue);
		}
		self->flushing = FALSE;
		GST_OBJECT_UNLOCK(self);
		break;
	case GST_EVENT_EOS:
	{
		struct pollfd pfd[2];
		pfd[0].fd = self->unlockfd[0];
		pfd[0].events = POLLIN;
		pfd[1].fd = self->fd;
		pfd[1].events = POLLIN;

		GST_PAD_PREROLL_UNLOCK(sink->sinkpad);
		while (1)
		{
			int retval = poll(pfd, 2, 250);
			if (retval < 0)
			{
				perror("poll in EVENT_EOS");
				ret = FALSE;
				break;
			}

			if (pfd[0].revents & POLLIN)
			{
				GST_DEBUG_OBJECT (self, "wait EOS aborted!!\n");
				ret = FALSE;
				break;
			}

			if (pfd[1].revents & POLLIN)
			{
				GST_DEBUG_OBJECT (self, "got buffer empty from driver!\n");
				break;
			}

			if (sink->flushing)
			{
				GST_DEBUG_OBJECT (self, "wait EOS flushing!!\n");
				ret = FALSE;
				break;
			}
		}
		GST_PAD_PREROLL_LOCK(sink->sinkpad);

		break;
	}
	case GST_EVENT_NEWSEGMENT:
	{
		GstFormat format;
		gboolean update;
		gdouble rate;
		gint64 start, end, pos;
		int skip = 0, repeat = 0;
		gst_event_parse_new_segment(event, &update, &rate, &format, &start, &end, &pos);
		GST_DEBUG_OBJECT(self, "GST_EVENT_NEWSEGMENT rate=%f\n", rate);
		if (format == GST_FORMAT_TIME)
		{
			self->timestamp_offset = start - pos;
			if (rate != self->rate)
			{
				if (rate > 1.0)
				{
					skip = (int)rate;
				}
				else if (rate < 1.0)
				{
					repeat = 1.0 / rate;
				}
				ioctl(self->fd, VIDEO_SLOWMOTION, repeat);
				ioctl(self->fd, VIDEO_FAST_FORWARD, skip);
				self->rate = rate;
			}
		}
		break;
	}

	default:
		break;
	}

	return ret;
}