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; } }
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; }
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; }
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; }
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; }
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; }
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 (¤t_video_segment, GST_FORMAT_UNDEFINED); break; case GST_EVENT_SEGMENT: gst_event_copy_segment (event, ¤t_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, ×tamp, &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); }
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; }
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, ×tamp, &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 }
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, ×tamp, &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; }
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); }