static gboolean gst_ffmpegscale_src_event (GstBaseTransform * trans, GstEvent * event) { GstFFMpegScale *scale; GstStructure *structure; gdouble pointer; gboolean res; scale = GST_FFMPEGSCALE (trans); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_NAVIGATION: event = gst_event_make_writable (event); structure = gst_event_writable_structure (event); if (gst_structure_get_double (structure, "pointer_x", &pointer)) { gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, pointer * scale->in_info.width / scale->out_info.width, NULL); } if (gst_structure_get_double (structure, "pointer_y", &pointer)) { gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, pointer * scale->in_info.height / scale->out_info.height, NULL); } break; default: break; } res = GST_BASE_TRANSFORM_CLASS (parent_class)->src_event (trans, event); return res; }
static gboolean gst_rtp_ssrc_demux_src_event (GstPad * pad, GstObject * parent, GstEvent * event) { GstRtpSsrcDemux *demux; const GstStructure *s; demux = GST_RTP_SSRC_DEMUX (parent); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_CUSTOM_UPSTREAM: case GST_EVENT_CUSTOM_BOTH: case GST_EVENT_CUSTOM_BOTH_OOB: s = gst_event_get_structure (event); if (s && !gst_structure_has_field (s, "ssrc")) { GstRtpSsrcDemuxPad *dpad = find_demux_pad_for_pad (demux, pad); if (dpad) { GstStructure *ws; event = gst_event_make_writable (event); ws = gst_event_writable_structure (event); gst_structure_set (ws, "ssrc", G_TYPE_UINT, dpad->ssrc, NULL); } } break; default: break; } return gst_pad_event_default (pad, parent, event); }
/* Probe on the output of a parser chain (the last * src pad) */ static GstPadProbeReturn parse_chain_output_probe (GstPad * pad, GstPadProbeInfo * info, DecodebinInputStream * input) { GstPadProbeReturn ret = GST_PAD_PROBE_OK; if (GST_IS_EVENT (GST_PAD_PROBE_INFO_DATA (info))) { GstEvent *ev = GST_PAD_PROBE_INFO_EVENT (info); GST_DEBUG_OBJECT (pad, "Got event %s", GST_EVENT_TYPE_NAME (ev)); switch (GST_EVENT_TYPE (ev)) { case GST_EVENT_STREAM_START: { GstStream *stream = NULL; guint group_id = G_MAXUINT32; gst_event_parse_group_id (ev, &group_id); GST_DEBUG_OBJECT (pad, "Got stream-start, group_id:%d, input %p", group_id, input->input); if (set_input_group_id (input->input, &group_id)) { ev = gst_event_make_writable (ev); gst_event_set_group_id (ev, group_id); GST_PAD_PROBE_INFO_DATA (info) = ev; } input->saw_eos = FALSE; gst_event_parse_stream (ev, &stream); /* FIXME : Would we ever end up with a stream already set on the input ?? */ if (stream) { if (input->active_stream != stream) { MultiQueueSlot *slot; if (input->active_stream) gst_object_unref (input->active_stream); input->active_stream = stream; /* We have the beginning of a stream, get a multiqueue slot and link to it */ g_mutex_lock (&input->dbin->selection_lock); slot = get_slot_for_input (input->dbin, input); link_input_to_slot (input, slot); g_mutex_unlock (&input->dbin->selection_lock); } else gst_object_unref (stream); } } break; case GST_EVENT_CAPS: { GstCaps *caps = NULL; gst_event_parse_caps (ev, &caps); GST_DEBUG_OBJECT (pad, "caps %" GST_PTR_FORMAT, caps); if (caps && input->active_stream) gst_stream_set_caps (input->active_stream, caps); } break; case GST_EVENT_EOS: input->saw_eos = TRUE; if (all_inputs_are_eos (input->dbin)) { GST_DEBUG_OBJECT (pad, "real input pad, marking as EOS"); check_all_streams_for_eos (input->dbin); } else { GstPad *peer = gst_pad_get_peer (input->srcpad); if (peer) { /* Send custom-eos event to multiqueue slot */ GstStructure *s; GstEvent *event; GST_DEBUG_OBJECT (pad, "Got EOS end of input stream, post custom-eos"); s = gst_structure_new_empty ("decodebin3-custom-eos"); event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s); gst_pad_send_event (peer, event); gst_object_unref (peer); } else { GST_FIXME_OBJECT (pad, "No peer, what should we do ?"); } } ret = GST_PAD_PROBE_DROP; break; case GST_EVENT_FLUSH_STOP: GST_DEBUG_OBJECT (pad, "Clear saw_eos flag"); input->saw_eos = FALSE; default: break; } } else if (GST_IS_QUERY (GST_PAD_PROBE_INFO_DATA (info))) { GstQuery *q = GST_PAD_PROBE_INFO_QUERY (info); GST_DEBUG_OBJECT (pad, "Seeing query %s", GST_QUERY_TYPE_NAME (q)); /* If we have a parser, we want to reply to the caps query */ /* FIXME: Set a flag when the input stream is created for * streams where we shouldn't reply to these queries */ if (GST_QUERY_TYPE (q) == GST_QUERY_CAPS && (info->type & GST_PAD_PROBE_TYPE_PULL)) { GstCaps *filter = NULL; GstCaps *allowed; gst_query_parse_caps (q, &filter); allowed = get_parser_caps_filter (input->dbin, filter); GST_DEBUG_OBJECT (pad, "Intercepting caps query, setting %" GST_PTR_FORMAT, allowed); gst_query_set_caps_result (q, allowed); gst_caps_unref (allowed); ret = GST_PAD_PROBE_HANDLED; } else if (GST_QUERY_TYPE (q) == GST_QUERY_ACCEPT_CAPS) { GstCaps *prop = NULL; gst_query_parse_accept_caps (q, &prop); /* Fast check against target caps */ if (gst_caps_can_intersect (prop, input->dbin->caps)) gst_query_set_accept_caps_result (q, TRUE); else { gboolean accepted = check_parser_caps_filter (input->dbin, prop); /* check against caps filter */ gst_query_set_accept_caps_result (q, accepted); GST_DEBUG_OBJECT (pad, "ACCEPT_CAPS query, returning %d", accepted); } ret = GST_PAD_PROBE_HANDLED; } } return ret; }
static gboolean gst_rtp_ulpfec_dec_handle_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) { GstRtpUlpFecDec *self = GST_RTP_ULPFEC_DEC (parent); gboolean forward = TRUE; GST_LOG_OBJECT (self, "Received event %" GST_PTR_FORMAT, event); if (GST_FLOW_OK == self->chain_return_val && GST_EVENT_CUSTOM_DOWNSTREAM == GST_EVENT_TYPE (event) && gst_event_has_name (event, "GstRTPPacketLost")) { guint seqnum; GstClockTime timestamp, duration; GstStructure *s; event = gst_event_make_writable (event); s = gst_event_writable_structure (event); g_assert (self->have_caps_ssrc); g_assert (self->storage); if (!gst_structure_get (s, "seqnum", G_TYPE_UINT, &seqnum, "timestamp", G_TYPE_UINT64, ×tamp, "duration", G_TYPE_UINT64, &duration, NULL)) g_assert_not_reached (); forward = gst_rtp_ulpfec_dec_handle_packet_loss (self, seqnum, timestamp, duration); if (forward) { gst_structure_remove_field (s, "seqnum"); gst_structure_set (s, "might-have-been-fec", G_TYPE_BOOLEAN, TRUE, NULL); ++self->packets_unrecovered; } else { ++self->packets_recovered; } GST_DEBUG_OBJECT (self, "Unrecovered / Recovered: %lu / %lu", (gulong) self->packets_unrecovered, (gulong) self->packets_recovered); } else if (GST_EVENT_CAPS == GST_EVENT_TYPE (event)) { GstCaps *caps; gboolean have_caps_pt = FALSE; gboolean have_caps_ssrc = FALSE; guint caps_ssrc = 0; gint caps_pt = 0; gst_event_parse_caps (event, &caps); have_caps_ssrc = gst_structure_get_uint (gst_caps_get_structure (caps, 0), "ssrc", &caps_ssrc); have_caps_pt = gst_structure_get_int (gst_caps_get_structure (caps, 0), "payload", &caps_pt); if (self->have_caps_ssrc != have_caps_ssrc || self->caps_ssrc != caps_ssrc) GST_DEBUG_OBJECT (self, "SSRC changed %u, 0x%08x -> %u, 0x%08x", self->have_caps_ssrc, self->caps_ssrc, have_caps_ssrc, caps_ssrc); if (self->have_caps_pt != have_caps_pt || self->caps_pt != caps_pt) GST_DEBUG_OBJECT (self, "PT changed %u, %u -> %u, %u", self->have_caps_pt, self->caps_pt, have_caps_pt, caps_pt); self->have_caps_ssrc = have_caps_ssrc; self->have_caps_pt = have_caps_pt; self->caps_ssrc = caps_ssrc; self->caps_pt = caps_pt; } if (forward) return gst_pad_push_event (self->srcpad, event); gst_event_unref (event); return TRUE; }