void
gst_kate_util_decoder_base_segment_event (GstKateDecoderBase * decoder,
    GstEvent * event)
{
  GstSegment seg;

  gst_event_copy_segment (event, &seg);

  GST_DEBUG_OBJECT (decoder, "kate pad segment: %" GST_SEGMENT_FORMAT, &seg);

  decoder->kate_segment = seg;
}
static gboolean
gst_timecodewait_asink_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  GstTimeCodeWait *self = GST_TIMECODEWAIT (parent);
  GST_LOG_OBJECT (pad, "Got %s event", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
      g_mutex_lock (&self->mutex);
      self->running_time_of_timecode = GST_CLOCK_TIME_NONE;
      gst_event_copy_segment (event, &self->asegment);
      if (self->asegment.format != GST_FORMAT_TIME) {
        GST_ERROR_OBJECT (self, "Invalid segment format");
        g_mutex_unlock (&self->mutex);
        return FALSE;
      }
      self->asegment.position = GST_CLOCK_TIME_NONE;
      g_mutex_unlock (&self->mutex);
      break;
    case GST_EVENT_FLUSH_START:
      g_mutex_lock (&self->mutex);
      self->audio_flush_flag = TRUE;
      g_cond_signal (&self->cond);
      g_mutex_unlock (&self->mutex);
      break;
    case GST_EVENT_FLUSH_STOP:
      g_mutex_lock (&self->mutex);
      self->audio_flush_flag = FALSE;
      self->running_time_of_timecode = GST_CLOCK_TIME_NONE;
      gst_segment_init (&self->asegment, GST_FORMAT_UNDEFINED);
      self->asegment.position = GST_CLOCK_TIME_NONE;
      g_mutex_unlock (&self->mutex);
      break;
    case GST_EVENT_CAPS:{
      GstCaps *caps;
      gst_event_parse_caps (event, &caps);
      GST_DEBUG_OBJECT (self, "Got caps %" GST_PTR_FORMAT, caps);
      g_mutex_lock (&self->mutex);
      if (!gst_audio_info_from_caps (&self->ainfo, caps)) {
        g_mutex_unlock (&self->mutex);
        return FALSE;
      }
      self->running_time_of_timecode = GST_CLOCK_TIME_NONE;
      g_mutex_unlock (&self->mutex);
      break;
    }
    default:
      break;
  }

  return gst_pad_event_default (pad, parent, event);
}
static gboolean
gst_raw_parse_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstRawParse *rp = GST_RAW_PARSE (parent);
  gboolean ret;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_EOS:
    case GST_EVENT_FLUSH_STOP:
      /* Only happens in push mode */
      gst_raw_parse_reset (rp);
      ret = gst_pad_push_event (rp->srcpad, event);
      break;
    case GST_EVENT_SEGMENT:
    {
      GstSegment segment;

      /* Only happens in push mode */

      gst_event_copy_segment (event, &segment);

      if (segment.format != GST_FORMAT_TIME) {
        gst_event_unref (event);

        ret =
            gst_raw_parse_convert (rp, segment.format, segment.start,
            GST_FORMAT_TIME, (gint64 *) & segment.start);
        ret &= gst_raw_parse_convert (rp, segment.format, segment.time,
            GST_FORMAT_TIME, (gint64 *) & segment.time);
        ret &= gst_raw_parse_convert (rp, segment.format, segment.stop,
            GST_FORMAT_TIME, (gint64 *) & segment.stop);
        if (!ret) {
          GST_ERROR_OBJECT (rp,
              "Failed converting to GST_FORMAT_TIME format (%d)",
              segment.format);
          break;
        }

        event = gst_event_new_segment (&segment);
      }

      gst_segment_copy_into (&segment, &rp->segment);

      ret = gst_pad_push_event (rp->srcpad, event);
      break;
    }
    default:
      ret = gst_pad_event_default (rp->sinkpad, parent, event);
      break;
  }

  return ret;
}
static gboolean
gst_rtp_mux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstRTPMux *mux = GST_RTP_MUX (parent);
  gboolean is_pad;
  gboolean ret;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      ret = gst_rtp_mux_setcaps (pad, mux, caps);
      gst_event_unref (event);
      return ret;
    }
    case GST_EVENT_FLUSH_STOP:
    {
      GST_OBJECT_LOCK (mux);
      mux->last_stop = GST_CLOCK_TIME_NONE;
      GST_OBJECT_UNLOCK (mux);
      break;
    }
    case GST_EVENT_SEGMENT:
    {
      GstRTPMuxPadPrivate *padpriv;

      GST_OBJECT_LOCK (mux);
      padpriv = gst_pad_get_element_private (pad);

      if (padpriv) {
        gst_event_copy_segment (event, &padpriv->segment);
      }
      GST_OBJECT_UNLOCK (mux);
      break;
    }
    default:
      break;
  }

  GST_OBJECT_LOCK (mux);
  is_pad = (pad == mux->last_pad);
  GST_OBJECT_UNLOCK (mux);

  if (is_pad) {
    return gst_pad_push_event (mux->srcpad, event);
  } else {
    gst_event_unref (event);
    return TRUE;
  }
}
Exemple #5
0
static gboolean
mpegts_base_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res = TRUE;
  gboolean hard;
  MpegTSBase *base = GST_MPEGTS_BASE (parent);
  gboolean is_sticky = GST_EVENT_IS_STICKY (event);

  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_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 (is_sticky)
    res = TRUE;

  return res;
}
static gboolean
gst_rtp_base_payload_sink_event_default (GstRTPBasePayload * rtpbasepayload,
    GstEvent * event)
{
  GstObject *parent = GST_OBJECT_CAST (rtpbasepayload);
  gboolean res = FALSE;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_START:
      res = gst_pad_event_default (rtpbasepayload->sinkpad, parent, event);
      break;
    case GST_EVENT_FLUSH_STOP:
      res = gst_pad_event_default (rtpbasepayload->sinkpad, parent, event);
      gst_segment_init (&rtpbasepayload->segment, GST_FORMAT_UNDEFINED);
      break;
    case GST_EVENT_CAPS:
    {
      GstRTPBasePayloadClass *rtpbasepayload_class;
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      GST_DEBUG_OBJECT (rtpbasepayload, "setting caps %" GST_PTR_FORMAT, caps);

      rtpbasepayload_class = GST_RTP_BASE_PAYLOAD_GET_CLASS (rtpbasepayload);
      if (rtpbasepayload_class->set_caps)
        res = rtpbasepayload_class->set_caps (rtpbasepayload, caps);

      gst_event_unref (event);
      break;
    }
    case GST_EVENT_SEGMENT:
    {
      GstSegment *segment;

      segment = &rtpbasepayload->segment;
      gst_event_copy_segment (event, segment);

      rtpbasepayload->priv->base_offset = GST_BUFFER_OFFSET_NONE;

      GST_DEBUG_OBJECT (rtpbasepayload,
          "configured SEGMENT %" GST_SEGMENT_FORMAT, segment);
      res = gst_pad_event_default (rtpbasepayload->sinkpad, parent, event);
      break;
    }
    default:
      res = gst_pad_event_default (rtpbasepayload->sinkpad, parent, event);
      break;
  }
  return res;
}
static GstPadProbeReturn
handle_output (GstPad * pad, GstPadProbeInfo * info, StreamInfo * si)
{
  GstClockTime start, end;
  GstBuffer *buf;

  GST_LOG_OBJECT (pad, "Fired probe type 0x%x", info->type);

  if (info->type & GST_PAD_PROBE_TYPE_BUFFER_LIST) {
    g_warning ("Buffer list handling not implemented");
    return GST_PAD_PROBE_DROP;
  }

  if (info->type & GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM) {
    GstEvent *event = gst_pad_probe_info_get_event (info);
    switch (GST_EVENT_TYPE (event)) {
      case GST_EVENT_SEGMENT:
        gst_event_copy_segment (event, &si->seg);
        break;
      case GST_EVENT_EOS:
        dump_times (si);
        break;
      default:
        break;
    }
    return GST_PAD_PROBE_PASS;
  }

  buf = gst_pad_probe_info_get_buffer (info);
  if (!GST_BUFFER_PTS_IS_VALID (buf))
    goto done;
  end = start = GST_BUFFER_PTS (buf);

  if (GST_BUFFER_DURATION_IS_VALID (buf))
    end += GST_BUFFER_DURATION (buf);

  gst_segment_clip (&si->seg, GST_FORMAT_TIME, start, end, &start, &end);
  start = gst_segment_to_stream_time (&si->seg, GST_FORMAT_TIME, start);
  end = gst_segment_to_stream_time (&si->seg, GST_FORMAT_TIME, end);

  GST_DEBUG_OBJECT (pad, "new buffer %" GST_TIME_FORMAT
      " to %" GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (end));

  /* Now extend measured time range to include new times */
  extend_times (si, start, end);

done:
  return GST_PAD_PROBE_PASS;
}
Exemple #8
0
static gboolean
gst_y4m_dec_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res;
  GstY4mDec *y4mdec;

  y4mdec = GST_Y4M_DEC (parent);

  GST_DEBUG_OBJECT (y4mdec, "event");

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_START:
      res = gst_pad_push_event (y4mdec->srcpad, event);
      break;
    case GST_EVENT_FLUSH_STOP:
      res = gst_pad_push_event (y4mdec->srcpad, event);
      break;
    case GST_EVENT_SEGMENT:
    {
      GstSegment seg;

      gst_event_copy_segment (event, &seg);

      GST_DEBUG ("segment: %" GST_SEGMENT_FORMAT, &seg);

      if (seg.format == GST_FORMAT_BYTES) {
        y4mdec->segment = seg;
        y4mdec->have_new_segment = TRUE;
      }

      res = TRUE;
      /* not sure why it's not forwarded, but let's unref it so it
         doesn't leak, remove the unref if it gets forwarded again */
      gst_event_unref (event);
      //res = gst_pad_push_event (y4mdec->srcpad, event);
    }
      break;
    case GST_EVENT_EOS:
      res = gst_pad_push_event (y4mdec->srcpad, event);
      break;
    default:
      res = gst_pad_push_event (y4mdec->srcpad, event);
      break;
  }

  return res;
}
static gboolean
gst_overlay_composition_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  GstOverlayComposition *self = GST_OVERLAY_COMPOSITION (parent);
  gboolean ret = FALSE;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
      gst_event_copy_segment (event, &self->segment);
      ret = gst_pad_event_default (pad, parent, event);
      break;
    case GST_EVENT_CAPS:{
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      if (!gst_video_info_from_caps (&self->info, caps)) {
        gst_event_unref (event);
        ret = FALSE;
        break;
      }

      if (!gst_overlay_composition_negotiate (self, caps)) {
        gst_event_unref (event);
        ret = FALSE;
        break;
      }

      gst_caps_replace (&self->caps, caps);

      ret = TRUE;
      gst_event_unref (event);

      break;
    }
    case GST_EVENT_FLUSH_STOP:
      gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED);
      ret = gst_pad_event_default (pad, parent, event);
      break;
    default:
      ret = gst_pad_event_default (pad, parent, event);
      break;
  }

  return ret;
}
Exemple #10
0
static gboolean
gst_fluid_dec_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res;
  GstFluidDec *fluiddec = GST_FLUID_DEC (parent);

  GST_DEBUG_OBJECT (pad, "%s event received", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      caps = gst_caps_new_simple ("audio/x-raw",
          "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
          "rate", G_TYPE_INT, FLUID_DEC_RATE,
          "channels", G_TYPE_INT, 2,
          "layout", G_TYPE_STRING, "interleaved", NULL);

      fluid_synth_set_sample_rate (fluiddec->synth, FLUID_DEC_RATE);

      res = gst_pad_push_event (fluiddec->srcpad, gst_event_new_caps (caps));
      gst_caps_unref (caps);
      break;
    }
    case GST_EVENT_SEGMENT:
      gst_event_copy_segment (event, &fluiddec->segment);
      GST_DEBUG_OBJECT (fluiddec, "configured segment %" GST_SEGMENT_FORMAT,
          &fluiddec->segment);
      res = gst_pad_event_default (pad, parent, event);
      break;
    case GST_EVENT_FLUSH_STOP:
      gst_fluid_dec_reset (fluiddec);
      res = gst_pad_event_default (pad, parent, event);
      break;
    case GST_EVENT_EOS:
      /* FIXME, push last samples */
      res = gst_pad_event_default (pad, parent, event);
      break;
    default:
      res = gst_pad_event_default (pad, parent, event);
      break;
  }
  return res;
}
static gboolean
gst_play_sink_convert_bin_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  GstPlaySinkConvertBin *self = GST_PLAY_SINK_CONVERT_BIN (parent);
  gboolean ret;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      ret = gst_play_sink_convert_bin_sink_setcaps (self, caps);
      break;
    }
    default:
      break;
  }

  ret = gst_pad_event_default (pad, parent, gst_event_ref (event));

  if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
    GstSegment seg;

    GST_PLAY_SINK_CONVERT_BIN_LOCK (self);
    gst_event_copy_segment (event, &seg);

    GST_DEBUG_OBJECT (self, "Segment before %" GST_SEGMENT_FORMAT,
        &self->segment);
    self->segment = seg;
    GST_DEBUG_OBJECT (self, "Segment after %" GST_SEGMENT_FORMAT,
        &self->segment);
    GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);
  } else if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
    GST_PLAY_SINK_CONVERT_BIN_LOCK (self);
    GST_DEBUG_OBJECT (self, "Resetting segment");
    gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED);
    GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);
  }

  gst_event_unref (event);

  return ret;
}
static gboolean
gst_monoscope_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstMonoscope *monoscope;
  gboolean res;

  monoscope = GST_MONOSCOPE (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_START:
      res = gst_pad_push_event (monoscope->srcpad, event);
      break;
    case GST_EVENT_FLUSH_STOP:
      gst_monoscope_reset (monoscope);
      res = gst_pad_push_event (monoscope->srcpad, event);
      break;
    case GST_EVENT_SEGMENT:
    {
      /* the newsegment values are used to clip the input samples
       * and to convert the incomming timestamps to running time so
       * we can do QoS */
      gst_event_copy_segment (event, &monoscope->segment);

      res = gst_pad_push_event (monoscope->srcpad, event);
      break;
    }
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      gst_monoscope_sink_setcaps (monoscope, caps);
      gst_event_unref (event);
      res = TRUE;
      break;
    }
    default:
      res = gst_pad_push_event (monoscope->srcpad, event);
      break;
  }

  return res;
}
Exemple #13
0
static GstBuffer *
dequeue_buffer (GstAppSink * appsink)
{
  GstAppSinkPrivate *priv = appsink->priv;
  GstBuffer *buffer;

  do {
    GstMiniObject *obj;

    obj = g_queue_pop_head (priv->queue);

    if (GST_IS_BUFFER (obj)) {
      buffer = GST_BUFFER_CAST (obj);
      GST_DEBUG_OBJECT (appsink, "dequeued buffer %p", buffer);
      priv->num_buffers--;
      break;
    } else if (GST_IS_EVENT (obj)) {
      GstEvent *event = GST_EVENT_CAST (obj);

      switch (GST_EVENT_TYPE (obj)) {
        case GST_EVENT_CAPS:
        {
          GstCaps *caps;

          gst_event_parse_caps (event, &caps);
          GST_DEBUG_OBJECT (appsink, "activating caps %" GST_PTR_FORMAT, caps);
          gst_caps_replace (&priv->last_caps, caps);
          break;
        }
        case GST_EVENT_SEGMENT:
          gst_event_copy_segment (event, &priv->last_segment);
          GST_DEBUG_OBJECT (appsink, "activated segment %" GST_SEGMENT_FORMAT,
              &priv->last_segment);
          break;
        default:
          break;
      }
      gst_mini_object_unref (obj);
    }
  } while (TRUE);

  return buffer;
}
Exemple #14
0
static gboolean
gst_shape_wipe_video_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  GstShapeWipe *self = GST_SHAPE_WIPE (parent);
  gboolean ret;

  GST_LOG_OBJECT (pad, "Got %s event", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      ret = gst_shape_wipe_video_sink_setcaps (self, caps);
      gst_event_unref (event);
      break;
    }
    case GST_EVENT_SEGMENT:
    {
      GstSegment seg;

      gst_event_copy_segment (event, &seg);
      if (seg.format == GST_FORMAT_TIME) {
        GST_DEBUG_OBJECT (pad,
            "Got SEGMENT event in GST_FORMAT_TIME %" GST_PTR_FORMAT, &seg);
        self->segment = seg;
      } else {
        gst_segment_init (&self->segment, GST_FORMAT_TIME);
      }
    }
      /* fall through */
    case GST_EVENT_FLUSH_STOP:
      gst_shape_wipe_reset_qos (self);
      /* fall through */
    default:
      ret = gst_pad_push_event (self->srcpad, event);
      break;
  }

  return ret;
}
static gboolean
smart_encoder_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res = TRUE;
  GstSmartEncoder *smart_encoder = GST_SMART_ENCODER (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_STOP:
      smart_encoder_reset (smart_encoder);
      break;
    case GST_EVENT_SEGMENT:
    {
      gst_event_copy_segment (event, smart_encoder->segment);

      GST_DEBUG_OBJECT (smart_encoder, "segment: %" GST_SEGMENT_FORMAT,
          smart_encoder->segment);
      if (smart_encoder->segment->format != GST_FORMAT_TIME) {
        GST_ERROR
            ("smart_encoder can not handle streams not specified in GST_FORMAT_TIME");
        gst_event_unref (event);
        return FALSE;
      }

      /* And keep a copy for further usage */
      if (smart_encoder->newsegment)
        gst_event_unref (smart_encoder->newsegment);
      smart_encoder->newsegment = gst_event_ref (event);
    }
      break;
    case GST_EVENT_EOS:
      GST_DEBUG ("Eos, flushing remaining data");
      if (smart_encoder->segment->format == GST_FORMAT_TIME)
        gst_smart_encoder_push_pending_gop (smart_encoder);
      break;
    default:
      break;
  }

  res = gst_pad_push_event (smart_encoder->srcpad, event);

  return res;
}
Exemple #16
0
static gboolean
gst_goom_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res;
  GstGoom *goom;

  goom = GST_GOOM (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      res = gst_goom_sink_setcaps (goom, caps);
      gst_event_unref (event);
      break;
    }
    case GST_EVENT_FLUSH_START:
      res = gst_pad_push_event (goom->srcpad, event);
      break;
    case GST_EVENT_FLUSH_STOP:
      gst_goom_reset (goom);
      res = gst_pad_push_event (goom->srcpad, event);
      break;
    case GST_EVENT_SEGMENT:
    {
      /* the newsegment values are used to clip the input samples
       * and to convert the incomming timestamps to running time so
       * we can do QoS */
      gst_event_copy_segment (event, &goom->segment);

      res = gst_pad_push_event (goom->srcpad, event);
      break;
    }
    default:
      res = gst_pad_push_event (goom->srcpad, event);
      break;
  }

  return res;
}
static gboolean
output_vevent (GstPad * pad, GstObject * parent, GstEvent * event)
{
  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_STOP:
      gst_segment_init (&current_video_segment, GST_FORMAT_UNDEFINED);
      break;
    case GST_EVENT_SEGMENT:
      gst_event_copy_segment (event, &current_video_segment);
      break;
    case GST_EVENT_EOS:
      got_eos = TRUE;
      break;
    default:
      break;
  }

  gst_event_unref (event);
  return TRUE;
}
static gboolean
gst_vaapidecode_sink_event (GstVideoDecoder * vdec, GstEvent * event)
{
  GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
    {
      /* Keep segment event to refer to rate so that
       * vaapidecode can handle reverse playback
       */
      gst_event_copy_segment (event, &decode->in_segment);
      break;
    }
    default:
      break;
  }

  return GST_VIDEO_DECODER_CLASS (parent_class)->sink_event (vdec, event);
}
static gboolean
gst_flxdec_sink_event_handler (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  GstFlxDec *flxdec;
  gboolean ret;

  flxdec = GST_FLXDEC (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
    {
      gst_event_copy_segment (event, &flxdec->segment);
      if (flxdec->segment.format != GST_FORMAT_TIME) {
        GST_DEBUG_OBJECT (flxdec, "generating TIME segment");
        gst_segment_init (&flxdec->segment, GST_FORMAT_TIME);
        gst_event_unref (event);
        event = gst_event_new_segment (&flxdec->segment);
      }

      if (gst_pad_has_current_caps (flxdec->srcpad)) {
        ret = gst_pad_event_default (pad, parent, event);
      } else {
        flxdec->need_segment = TRUE;
        gst_event_unref (event);
        ret = TRUE;
      }
      break;
    }
    case GST_EVENT_FLUSH_STOP:
      gst_segment_init (&flxdec->segment, GST_FORMAT_UNDEFINED);
      ret = gst_pad_event_default (pad, parent, event);
      break;
    default:
      ret = gst_pad_event_default (pad, parent, event);
      break;
  }

  return ret;
}
static gboolean
gst_videoframe_audiolevel_vsink_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  GstVideoFrameAudioLevel *self = GST_VIDEOFRAME_AUDIOLEVEL (parent);
  GST_LOG_OBJECT (pad, "Got %s event", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
      g_mutex_lock (&self->mutex);
      g_queue_foreach (&self->vtimeq, (GFunc) g_free, NULL);
      g_queue_clear (&self->vtimeq);
      g_mutex_unlock (&self->mutex);
      gst_event_copy_segment (event, &self->vsegment);
      if (self->vsegment.format != GST_FORMAT_TIME)
        return FALSE;
      self->vsegment.position = GST_CLOCK_TIME_NONE;
      break;
    case GST_EVENT_GAP:
      return TRUE;
    case GST_EVENT_EOS:
      g_mutex_lock (&self->mutex);
      self->video_eos_flag = TRUE;
      g_cond_signal (&self->cond);
      g_mutex_unlock (&self->mutex);
      break;
    case GST_EVENT_FLUSH_STOP:
      g_mutex_lock (&self->mutex);
      g_queue_foreach (&self->vtimeq, (GFunc) g_free, NULL);
      g_queue_clear (&self->vtimeq);
      gst_segment_init (&self->vsegment, GST_FORMAT_UNDEFINED);
      g_cond_signal (&self->cond);
      g_mutex_unlock (&self->mutex);
      self->vsegment.position = GST_CLOCK_TIME_NONE;
      break;
    default:
      break;
  }
  return gst_pad_event_default (pad, parent, event);
}
GstPadProbeReturn GstEnginePipeline::DecodebinProbe(GstPad* pad,
        GstPadProbeInfo* info,
        gpointer data) {
    GstEnginePipeline* instance = reinterpret_cast<GstEnginePipeline*>(data);
    const GstPadProbeType info_type = GST_PAD_PROBE_INFO_TYPE(info);

    if (info_type & GST_PAD_PROBE_TYPE_BUFFER) {
        // The decodebin produced a buffer.  Record its end time, so we can offset
        // the buffers produced by the next decodebin when transitioning to the next
        // song.
        GstBuffer* buffer = GST_PAD_PROBE_INFO_BUFFER(info);

        GstClockTime timestamp = GST_BUFFER_TIMESTAMP(buffer);
        GstClockTime duration = GST_BUFFER_DURATION(buffer);
        if (timestamp == GST_CLOCK_TIME_NONE) {
            timestamp = instance->last_decodebin_segment_.position;
        }

        if (duration != GST_CLOCK_TIME_NONE) {
            timestamp += duration;
        }

        instance->last_decodebin_segment_.position = timestamp;
    } else if (info_type & GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM) {
        GstEvent* event = GST_PAD_PROBE_INFO_EVENT(info);
        GstEventType event_type = GST_EVENT_TYPE(event);

        if (event_type == GST_EVENT_SEGMENT) {
            // A new segment started, we need to save this to calculate running time
            // offsets later.
            gst_event_copy_segment(event, &instance->last_decodebin_segment_);
        } else if (event_type == GST_EVENT_FLUSH_START) {
            // A flushing seek resets the running time to 0, so remove any offset
            // we set on this pad before.
            gst_pad_set_offset(pad, 0);
        }
    }

    return GST_PAD_PROBE_OK;
}
static gboolean
gst_rdt_depay_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstRDTDepay *depay;
  gboolean res = TRUE;

  depay = GST_RDT_DEPAY (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      res = gst_rdt_depay_setcaps (pad, caps);
      gst_event_unref (event);
      break;
    }
    case GST_EVENT_FLUSH_STOP:
      res = gst_pad_push_event (depay->srcpad, event);

      gst_segment_init (&depay->segment, GST_FORMAT_UNDEFINED);
      depay->need_newsegment = TRUE;
      depay->next_seqnum = -1;
      break;
    case GST_EVENT_SEGMENT:
    {
      gst_event_copy_segment (event, &depay->segment);
      /* don't pass the event downstream, we generate our own segment
       * including the NTP time and other things we receive in caps */
      gst_event_unref (event);
      break;
    }
    default:
      /* pass other events forward */
      res = gst_pad_push_event (depay->srcpad, event);
      break;
  }
  return res;
}
static GstPadProbeReturn
gst_hls_sink_ghost_event_probe (GstPad * pad, GstPadProbeInfo * info,
    gpointer data)
{
  GstHlsSink *sink = GST_HLS_SINK_CAST (data);
  GstEvent *event = gst_pad_probe_info_get_event (info);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
    {
      gst_event_copy_segment (event, &sink->segment);
      break;
    }
    case GST_EVENT_FLUSH_STOP:
      gst_segment_init (&sink->segment, GST_FORMAT_UNDEFINED);
      break;
    case GST_EVENT_CUSTOM_DOWNSTREAM:
    {
      GstClockTime timestamp;
      GstClockTime running_time, stream_time;
      gboolean all_headers;
      guint count;

      if (!gst_video_event_is_force_key_unit (event))
        break;

      gst_event_replace (&sink->force_key_unit_event, event);
      gst_video_event_parse_downstream_force_key_unit (event,
          &timestamp, &stream_time, &running_time, &all_headers, &count);
      GST_INFO_OBJECT (sink, "setting index %d", count);
      sink->index = count;
      break;
    }
    default:
      break;
  }

  return GST_PAD_PROBE_OK;
}
static gboolean
gst_merger_event_sinkl (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstMerger *merger = GST_MERGER (parent);
  gboolean ret;

  GST_DEBUG_OBJECT (pad, "got event %s", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {

    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);

      GST_DEBUG_OBJECT (pad, "event caps are %" GST_PTR_FORMAT, caps);
      ret = gst_merger_setcaps_srcv (merger, caps);

      break;
    }

    case GST_EVENT_EOS:
      process_eos (merger);
      gst_event_unref (event);
      ret = TRUE;
      break;
    case GST_EVENT_SEGMENT:
      gst_event_copy_segment (event, &merger->s_segment);
      GST_DEBUG_OBJECT (merger, "segment: %" GST_SEGMENT_FORMAT,
          &merger->s_segment);
    default:
      ret = gst_pad_event_default (pad, parent, event);
      break;
  }
  return ret;
}
static gboolean
gst_output_selector_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res = TRUE;
  GstOutputSelector *sel;
  GstPad *active = NULL;

  sel = GST_OUTPUT_SELECTOR (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_EOS:
    {
      res = gst_output_selector_forward_event (sel, event);
      break;
    }
    case GST_EVENT_SEGMENT:
    {
      gst_event_copy_segment (event, &sel->segment);
      GST_DEBUG_OBJECT (sel, "configured SEGMENT %" GST_SEGMENT_FORMAT,
          &sel->segment);
      /* fall through */
    }
    default:
    {
      active = gst_output_selector_get_active (sel);
      if (active) {
        res = gst_pad_push_event (active, event);
        gst_object_unref (active);
      } else {
        gst_event_unref (event);
      }
      break;
    }
  }

  return res;
}
static GstEvent *
gst_tag_mux_adjust_event_offsets (GstTagMux * mux,
    const GstEvent * newsegment_event)
{
  GstSegment segment;

  gst_event_copy_segment ((GstEvent *) newsegment_event, &segment);

  g_assert (segment.format == GST_FORMAT_BYTES);

  if (segment.start != -1)
    segment.start += mux->priv->start_tag_size;
  if (segment.stop != -1)
    segment.stop += mux->priv->start_tag_size;
  if (segment.time != -1)
    segment.time += mux->priv->start_tag_size;

  GST_DEBUG_OBJECT (mux, "adjusting newsegment event offsets to start=%"
      G_GINT64_FORMAT ", stop=%" G_GINT64_FORMAT ", cur=%" G_GINT64_FORMAT
      " (delta = +%" G_GSIZE_FORMAT ")", segment.start, segment.stop,
      segment.time, mux->priv->start_tag_size);

  return gst_event_new_segment (&segment);
}
Exemple #27
0
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;
}
Exemple #28
0
static gboolean
gst_dvd_spu_video_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstDVDSpu *dvdspu = (GstDVDSpu *) parent;
  SpuState *state = &dvdspu->spu_state;
  gboolean res = TRUE;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      res = gst_dvd_spu_video_set_caps (pad, caps);
      if (res)
        res = gst_pad_push_event (dvdspu->srcpad, event);
      else
        gst_event_unref (event);
      break;
    }
    case GST_EVENT_CUSTOM_DOWNSTREAM:
    case GST_EVENT_CUSTOM_DOWNSTREAM_OOB:
    {
      gboolean in_still;

      if (gst_video_event_parse_still_frame (event, &in_still)) {
        GstBuffer *to_push = NULL;

        /* Forward the event before handling */
        res = gst_pad_event_default (pad, parent, event);

        GST_DEBUG_OBJECT (dvdspu,
            "Still frame event on video pad: in-still = %d", in_still);

        DVD_SPU_LOCK (dvdspu);
        if (in_still) {
          state->flags |= SPU_STATE_STILL_FRAME;
          /* Entering still. Advance the SPU to make sure the state is 
           * up to date */
          gst_dvd_spu_check_still_updates (dvdspu);
          /* And re-draw the still frame to make sure it appears on
           * screen, otherwise the last frame  might have been discarded 
           * by QoS */
          gst_dvd_spu_redraw_still (dvdspu, TRUE);
          to_push = dvdspu->pending_frame;
          dvdspu->pending_frame = NULL;
        } else {
          state->flags &= ~(SPU_STATE_STILL_FRAME);
        }
        DVD_SPU_UNLOCK (dvdspu);
        if (to_push)
          gst_pad_push (dvdspu->srcpad, to_push);
      } else {
        GST_DEBUG_OBJECT (dvdspu,
            "Custom event %" GST_PTR_FORMAT " on video pad", event);
        res = gst_pad_event_default (pad, parent, event);
      }
      break;
    }
    case GST_EVENT_SEGMENT:
    {
      GstSegment seg;

      gst_event_copy_segment (event, &seg);

      if (seg.format != GST_FORMAT_TIME)
        return FALSE;

      /* Only print updates if they have an end time (don't print start_time
       * updates */
      GST_DEBUG_OBJECT (dvdspu, "video pad Segment: %" GST_SEGMENT_FORMAT,
          &seg);

      DVD_SPU_LOCK (dvdspu);

      if (seg.start > dvdspu->video_seg.position) {
        update_video_to_position (dvdspu, seg.start);
      }

      dvdspu->video_seg = seg;
      DVD_SPU_UNLOCK (dvdspu);

      res = gst_pad_event_default (pad, parent, event);
      break;
    }
    case GST_EVENT_GAP:
    {
      GstClockTime timestamp, duration;
      gst_event_parse_gap (event, &timestamp, &duration);
      if (GST_CLOCK_TIME_IS_VALID (duration))
        timestamp += duration;

      DVD_SPU_LOCK (dvdspu);
      GST_LOG_OBJECT (dvdspu, "Received GAP. Advancing to %" GST_TIME_FORMAT,
          GST_TIME_ARGS (timestamp));
      update_video_to_position (dvdspu, timestamp);
      DVD_SPU_UNLOCK (dvdspu);

      gst_event_unref (event);
      break;
    }
    case GST_EVENT_FLUSH_START:
      res = gst_pad_event_default (pad, parent, event);
      goto done;
    case GST_EVENT_FLUSH_STOP:
      res = gst_pad_event_default (pad, parent, event);

      DVD_SPU_LOCK (dvdspu);
      gst_segment_init (&dvdspu->video_seg, GST_FORMAT_UNDEFINED);
      gst_buffer_replace (&dvdspu->ref_frame, NULL);
      gst_buffer_replace (&dvdspu->pending_frame, NULL);

      DVD_SPU_UNLOCK (dvdspu);
      goto done;
    default:
      res = gst_pad_event_default (pad, parent, event);
      break;
  }

done:
  return res;
#if 0
error:
  gst_event_unref (event);
  return FALSE;
#endif
}
Exemple #29
0
static gboolean
gst_dvd_spu_subpic_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstDVDSpu *dvdspu = (GstDVDSpu *) parent;
  gboolean res = TRUE;

  /* Some events on the subpicture sink pad just get ignored, like 
   * FLUSH_START */
  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      res = gst_dvd_spu_subpic_set_caps (pad, caps);
      gst_event_unref (event);
      break;
    }
    case GST_EVENT_CUSTOM_DOWNSTREAM:
    case GST_EVENT_CUSTOM_DOWNSTREAM_STICKY:
    case GST_EVENT_CUSTOM_DOWNSTREAM_OOB:
    {
      const GstStructure *structure = gst_event_get_structure (event);
      gboolean need_push;

      if (!gst_structure_has_name (structure, "application/x-gst-dvd")) {
        res = gst_pad_event_default (pad, parent, event);
        break;
      }

      DVD_SPU_LOCK (dvdspu);
      if (GST_EVENT_IS_SERIALIZED (event)) {
        SpuPacket *spu_packet = g_new0 (SpuPacket, 1);
        GST_DEBUG_OBJECT (dvdspu,
            "Enqueueing DVD event on subpicture pad for later");
        spu_packet->event = event;
        g_queue_push_tail (dvdspu->pending_spus, spu_packet);
      } else {
        gst_dvd_spu_handle_dvd_event (dvdspu, event);
      }

      /* If the handle_dvd_event generated a pending frame, we
       * need to synchronise with the video pad's stream lock and push it.
       * This requires some dancing to preserve locking order and handle
       * flushes correctly */
      need_push = (dvdspu->pending_frame != NULL);
      DVD_SPU_UNLOCK (dvdspu);
      if (need_push) {
        GstBuffer *to_push = NULL;
        gboolean flushing;

        GST_LOG_OBJECT (dvdspu, "Going for stream lock");
        GST_PAD_STREAM_LOCK (dvdspu->videosinkpad);
        GST_LOG_OBJECT (dvdspu, "Got stream lock");
        GST_OBJECT_LOCK (dvdspu->videosinkpad);
        flushing = GST_PAD_IS_FLUSHING (dvdspu->videosinkpad);
        GST_OBJECT_UNLOCK (dvdspu->videosinkpad);

        DVD_SPU_LOCK (dvdspu);
        if (dvdspu->pending_frame == NULL || flushing) {
          /* Got flushed while waiting for the stream lock */
          DVD_SPU_UNLOCK (dvdspu);
        } else {
          to_push = dvdspu->pending_frame;
          dvdspu->pending_frame = NULL;

          DVD_SPU_UNLOCK (dvdspu);
          gst_pad_push (dvdspu->srcpad, to_push);
        }
        GST_LOG_OBJECT (dvdspu, "Dropping stream lock");
        GST_PAD_STREAM_UNLOCK (dvdspu->videosinkpad);
      }

      break;
    }
    case GST_EVENT_SEGMENT:
    {
      GstSegment seg;

      gst_event_copy_segment (event, &seg);

      /* Only print updates if they have an end time (don't print start_time
       * updates */
      GST_DEBUG_OBJECT (dvdspu, "subpic pad Segment: %" GST_SEGMENT_FORMAT,
          &seg);

      DVD_SPU_LOCK (dvdspu);

      dvdspu->subp_seg = seg;
      GST_LOG_OBJECT (dvdspu, "Subpicture segment now: %" GST_SEGMENT_FORMAT,
          &dvdspu->subp_seg);
      DVD_SPU_UNLOCK (dvdspu);

      gst_event_unref (event);
      break;
    }
    case GST_EVENT_GAP:
    {
      GstClockTime timestamp, duration;
      gst_event_parse_gap (event, &timestamp, &duration);
      if (GST_CLOCK_TIME_IS_VALID (duration))
        timestamp += duration;

      DVD_SPU_LOCK (dvdspu);
      dvdspu->subp_seg.position = timestamp;
      GST_LOG_OBJECT (dvdspu, "Received GAP. Segment now: %" GST_SEGMENT_FORMAT,
          &dvdspu->subp_seg);
      DVD_SPU_UNLOCK (dvdspu);

      gst_event_unref (event);
      break;
    }
    case GST_EVENT_FLUSH_START:
      gst_event_unref (event);
      goto done;
    case GST_EVENT_FLUSH_STOP:
      GST_DEBUG_OBJECT (dvdspu, "Have flush-stop event on SPU pad");
      DVD_SPU_LOCK (dvdspu);
      gst_segment_init (&dvdspu->subp_seg, GST_FORMAT_UNDEFINED);
      gst_dvd_spu_flush_spu_info (dvdspu, TRUE);
      DVD_SPU_UNLOCK (dvdspu);

      /* We don't forward flushes on the spu pad */
      gst_event_unref (event);
      goto done;
    case GST_EVENT_EOS:
      /* drop EOS on the subtitle pad, it means there are no more subtitles,
       * video might still continue, though */
      gst_event_unref (event);
      goto done;
      break;
    default:
      res = gst_pad_event_default (pad, parent, event);
      break;
  }

done:

  return res;
}
Exemple #30
0
static gboolean
gst_app_sink_event (GstBaseSink * sink, GstEvent * event)
{
  GstAppSink *appsink = GST_APP_SINK_CAST (sink);
  GstAppSinkPrivate *priv = appsink->priv;

  switch (event->type) {
    case GST_EVENT_SEGMENT:
      g_mutex_lock (&priv->mutex);
      GST_DEBUG_OBJECT (appsink, "receiving SEGMENT");
      g_queue_push_tail (priv->queue, gst_event_ref (event));
      if (!priv->preroll)
        gst_event_copy_segment (event, &priv->preroll_segment);
      g_mutex_unlock (&priv->mutex);
      break;
    case GST_EVENT_EOS:{
      gboolean emit = TRUE;

      g_mutex_lock (&priv->mutex);
      GST_DEBUG_OBJECT (appsink, "receiving EOS");
      priv->is_eos = TRUE;
      g_cond_signal (&priv->cond);
      g_mutex_unlock (&priv->mutex);

      g_mutex_lock (&priv->mutex);
      /* wait until all buffers are consumed or we're flushing.
       * Otherwise we might signal EOS before all buffers are
       * consumed, which is a bit confusing for the application
       */
      while (priv->num_buffers > 0 && !priv->flushing)
        g_cond_wait (&priv->cond, &priv->mutex);
      if (priv->flushing)
        emit = FALSE;
      g_mutex_unlock (&priv->mutex);

      if (emit) {
        /* emit EOS now */
        if (priv->callbacks.eos)
          priv->callbacks.eos (appsink, priv->user_data);
        else
          g_signal_emit (appsink, gst_app_sink_signals[SIGNAL_EOS], 0);
      }

      break;
    }
    case GST_EVENT_FLUSH_START:
      /* we don't have to do anything here, the base class will call unlock
       * which will make sure we exit the _render method */
      GST_DEBUG_OBJECT (appsink, "received FLUSH_START");
      break;
    case GST_EVENT_FLUSH_STOP:
      g_mutex_lock (&priv->mutex);
      GST_DEBUG_OBJECT (appsink, "received FLUSH_STOP");
      gst_app_sink_flush_unlocked (appsink);
      g_mutex_unlock (&priv->mutex);
      break;
    default:
      break;
  }
  return GST_BASE_SINK_CLASS (parent_class)->event (sink, event);
}