static void setup_ports (GstOmxBaseFilter *self) { GOmxCore *core; OMX_PARAM_PORTDEFINITIONTYPE *param; core = self->gomx; param = calloc (1, sizeof (OMX_PARAM_PORTDEFINITIONTYPE)); param->nSize = sizeof (OMX_PARAM_PORTDEFINITIONTYPE); param->nVersion.s.nVersionMajor = 1; param->nVersion.s.nVersionMinor = 1; /* Input port configuration. */ param->nPortIndex = 0; OMX_GetParameter (core->omx_handle, OMX_IndexParamPortDefinition, param); self->in_port = g_omx_core_setup_port (core, param); gst_pad_set_element_private (self->sinkpad, self->in_port); /* Output port configuration. */ param->nPortIndex = 1; OMX_GetParameter (core->omx_handle, OMX_IndexParamPortDefinition, param); self->out_port = g_omx_core_setup_port (core, param); gst_pad_set_element_private (self->srcpad, self->out_port); free (param); }
static void setup_ports (GstOmxBaseFilter * self) { /* Input port configuration. */ g_omx_port_setup (self->in_port); gst_pad_set_element_private (self->sinkpad, self->in_port); /* Output port configuration. */ g_omx_port_setup (self->out_port); gst_pad_set_element_private (self->srcpad, self->out_port); /* @todo: read from config file: */ if (g_getenv ("OMX_ALLOCATE_ON")) { GST_DEBUG_OBJECT (self, "OMX_ALLOCATE_ON"); self->in_port->omx_allocate = TRUE; self->out_port->omx_allocate = TRUE; self->share_input_buffer = FALSE; self->share_output_buffer = FALSE; } else if (g_getenv ("OMX_SHARE_HACK_ON")) { GST_DEBUG_OBJECT (self, "OMX_SHARE_HACK_ON"); self->share_input_buffer = TRUE; self->share_output_buffer = TRUE; } else if (g_getenv ("OMX_SHARE_HACK_OFF")) { GST_DEBUG_OBJECT (self, "OMX_SHARE_HACK_OFF"); self->share_input_buffer = FALSE; self->share_output_buffer = FALSE; } else { GST_DEBUG_OBJECT (self, "default sharing and allocation"); } GST_DEBUG_OBJECT (self, "omx_allocate: in: %d, out: %d", self->in_port->omx_allocate, self->out_port->omx_allocate); GST_DEBUG_OBJECT (self, "share_buffer: in: %d, out: %d", self->share_input_buffer, self->share_output_buffer); }
static void link_sinks (GstElement * mpegtsmux, GstPad ** src1, GstPad ** src2, GstPad ** src3, TestData * test_data) { GstPad *mux_sink1, *mux_sink2, *mux_sink3; /* link 3 sink pads, 2 video 1 audio */ *src1 = gst_pad_new_from_static_template (&video_src_template, "src1"); gst_pad_set_active (*src1, TRUE); gst_pad_set_element_private (*src1, test_data); gst_pad_set_event_function (*src1, src_event); mux_sink1 = gst_element_get_request_pad (mpegtsmux, "sink_1"); fail_unless (gst_pad_link (*src1, mux_sink1) == GST_PAD_LINK_OK); *src2 = gst_pad_new_from_static_template (&video_src_template, "src2"); gst_pad_set_active (*src2, TRUE); gst_pad_set_element_private (*src2, test_data); gst_pad_set_event_function (*src2, src_event); mux_sink2 = gst_element_get_request_pad (mpegtsmux, "sink_2"); fail_unless (gst_pad_link (*src2, mux_sink2) == GST_PAD_LINK_OK); *src3 = gst_pad_new_from_static_template (&audio_src_template, "src3"); gst_pad_set_active (*src3, TRUE); gst_pad_set_element_private (*src3, test_data); gst_pad_set_event_function (*src3, src_event); mux_sink3 = gst_element_get_request_pad (mpegtsmux, "sink_3"); fail_unless (gst_pad_link (*src3, mux_sink3) == GST_PAD_LINK_OK); gst_object_unref (mux_sink1); gst_object_unref (mux_sink2); gst_object_unref (mux_sink3); }
/* initialize the new element * instantiate pads and add them to element * set pad calback functions * initialize instance structure */ static void gst_srtp_dec_init (GstSrtpDec * filter) { filter->replay_window_size = DEFAULT_REPLAY_WINDOW_SIZE; filter->rtp_sinkpad = gst_pad_new_from_static_template (&rtp_sink_template, "rtp_sink"); gst_pad_set_event_function (filter->rtp_sinkpad, GST_DEBUG_FUNCPTR (gst_srtp_dec_sink_event_rtp)); gst_pad_set_query_function (filter->rtp_sinkpad, GST_DEBUG_FUNCPTR (gst_srtp_dec_sink_query_rtp)); gst_pad_set_iterate_internal_links_function (filter->rtp_sinkpad, GST_DEBUG_FUNCPTR (gst_srtp_dec_iterate_internal_links_rtp)); gst_pad_set_chain_function (filter->rtp_sinkpad, GST_DEBUG_FUNCPTR (gst_srtp_dec_chain_rtp)); filter->rtp_srcpad = gst_pad_new_from_static_template (&rtp_src_template, "rtp_src"); gst_pad_set_iterate_internal_links_function (filter->rtp_srcpad, GST_DEBUG_FUNCPTR (gst_srtp_dec_iterate_internal_links_rtp)); gst_pad_set_element_private (filter->rtp_sinkpad, filter->rtp_srcpad); gst_pad_set_element_private (filter->rtp_srcpad, filter->rtp_sinkpad); gst_element_add_pad (GST_ELEMENT (filter), filter->rtp_sinkpad); gst_element_add_pad (GST_ELEMENT (filter), filter->rtp_srcpad); filter->rtcp_sinkpad = gst_pad_new_from_static_template (&rtcp_sink_template, "rtcp_sink"); gst_pad_set_event_function (filter->rtcp_sinkpad, GST_DEBUG_FUNCPTR (gst_srtp_dec_sink_event_rtcp)); gst_pad_set_query_function (filter->rtcp_sinkpad, GST_DEBUG_FUNCPTR (gst_srtp_dec_sink_query_rtcp)); gst_pad_set_iterate_internal_links_function (filter->rtcp_sinkpad, GST_DEBUG_FUNCPTR (gst_srtp_dec_iterate_internal_links_rtcp)); gst_pad_set_chain_function (filter->rtcp_sinkpad, GST_DEBUG_FUNCPTR (gst_srtp_dec_chain_rtcp)); filter->rtcp_srcpad = gst_pad_new_from_static_template (&rtcp_src_template, "rtcp_src"); gst_pad_set_iterate_internal_links_function (filter->rtcp_srcpad, GST_DEBUG_FUNCPTR (gst_srtp_dec_iterate_internal_links_rtcp)); gst_pad_set_element_private (filter->rtcp_sinkpad, filter->rtcp_srcpad); gst_pad_set_element_private (filter->rtcp_srcpad, filter->rtcp_sinkpad); gst_element_add_pad (GST_ELEMENT (filter), filter->rtcp_sinkpad); gst_element_add_pad (GST_ELEMENT (filter), filter->rtcp_srcpad); filter->first_session = TRUE; filter->roc_changed = FALSE; }
static void switch_pads (GstHLSDemux * demux, GstCaps * newcaps) { GstPad *oldpad = demux->srcpad; GST_DEBUG ("Switching pads (oldpad:%p)", oldpad); /* First create and activate new pad */ demux->srcpad = gst_pad_new_from_static_template (&srctemplate, NULL); gst_pad_set_event_function (demux->srcpad, GST_DEBUG_FUNCPTR (gst_hls_demux_src_event)); gst_pad_set_query_function (demux->srcpad, GST_DEBUG_FUNCPTR (gst_hls_demux_src_query)); gst_pad_set_element_private (demux->srcpad, demux); gst_pad_set_active (demux->srcpad, TRUE); gst_pad_set_caps (demux->srcpad, newcaps); gst_element_add_pad (GST_ELEMENT (demux), demux->srcpad); gst_element_no_more_pads (GST_ELEMENT (demux)); if (oldpad) { /* Push out EOS */ gst_pad_push_event (oldpad, gst_event_new_eos ()); gst_pad_set_active (oldpad, FALSE); gst_element_remove_pad (GST_ELEMENT (demux), oldpad); } }
void GStreamerReader::InstallPadCallbacks() { GstPad* sinkpad = gst_element_get_static_pad(GST_ELEMENT(mVideoAppSink), "sink"); gst_pad_add_probe(sinkpad, (GstPadProbeType) (GST_PAD_PROBE_TYPE_SCHEDULING | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GST_PAD_PROBE_TYPE_EVENT_UPSTREAM | GST_PAD_PROBE_TYPE_EVENT_FLUSH), &GStreamerReader::EventProbeCb, this, nullptr); gst_pad_add_probe(sinkpad, GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM, GStreamerReader::QueryProbeCb, nullptr, nullptr); gst_pad_set_element_private(sinkpad, this); gst_object_unref(sinkpad); sinkpad = gst_element_get_static_pad(GST_ELEMENT(mAudioAppSink), "sink"); gst_pad_add_probe(sinkpad, (GstPadProbeType) (GST_PAD_PROBE_TYPE_SCHEDULING | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GST_PAD_PROBE_TYPE_EVENT_UPSTREAM | GST_PAD_PROBE_TYPE_EVENT_FLUSH), &GStreamerReader::EventProbeCb, this, nullptr); gst_object_unref(sinkpad); }
static void setup_ports (GstOmxBaseSink * self) { /* Input port configuration. */ g_omx_port_setup (self->in_port); gst_pad_set_element_private (self->sinkpad, self->in_port); }
static GstPad * fs_funnel_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * name) { GstPad *sinkpad; FsFunnelPadPrivate *priv = g_slice_alloc0 (sizeof(FsFunnelPadPrivate)); GST_DEBUG_OBJECT (element, "requesting pad"); sinkpad = gst_pad_new_from_template (templ, name); gst_pad_set_chain_function (sinkpad, GST_DEBUG_FUNCPTR (fs_funnel_chain)); gst_pad_set_event_function (sinkpad, GST_DEBUG_FUNCPTR (fs_funnel_event)); gst_pad_set_getcaps_function (sinkpad, GST_DEBUG_FUNCPTR (fs_funnel_getcaps)); gst_pad_set_bufferalloc_function (sinkpad, GST_DEBUG_FUNCPTR (fs_funnel_buffer_alloc)); gst_segment_init (&priv->segment, GST_FORMAT_UNDEFINED); gst_pad_set_element_private (sinkpad, priv); gst_pad_set_active (sinkpad, TRUE); gst_element_add_pad (element, sinkpad); return sinkpad; }
/* Must be called with lock! */ static void gst_stream_synchronizer_release_stream (GstStreamSynchronizer * self, GstSyncStream * stream) { GList *l; GST_DEBUG_OBJECT (self, "Releasing stream %d", stream->stream_number); for (l = self->streams; l; l = l->next) { if (l->data == stream) { self->streams = g_list_delete_link (self->streams, l); break; } } g_assert (l != NULL); if (self->streams == NULL) { self->have_group_id = TRUE; self->group_id = G_MAXUINT; } /* we can drop the lock, since stream exists now only local. * Moreover, we should drop, to prevent deadlock with STREAM_LOCK * (due to reverse lock order) when deactivating pads */ GST_STREAM_SYNCHRONIZER_UNLOCK (self); gst_pad_set_element_private (stream->srcpad, NULL); gst_pad_set_element_private (stream->sinkpad, NULL); gst_pad_set_active (stream->srcpad, FALSE); gst_element_remove_pad (GST_ELEMENT_CAST (self), stream->srcpad); gst_pad_set_active (stream->sinkpad, FALSE); gst_element_remove_pad (GST_ELEMENT_CAST (self), stream->sinkpad); g_cond_clear (&stream->stream_finish_cond); g_slice_free (GstSyncStream, stream); /* NOTE: In theory we have to check here if all streams * are EOS but the one that was removed wasn't and then * send EOS downstream. But due to the way how playsink * works this is not necessary and will only cause problems * for gapless playback. playsink will only add/remove pads * when it's reconfigured, which happens when the streams * change */ /* lock for good measure, since the caller had it */ GST_STREAM_SYNCHRONIZER_LOCK (self); }
static void gst_hls_demux_init (GstHLSDemux * demux, GstHLSDemuxClass * klass) { /* sink pad */ demux->sinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink"); gst_pad_set_chain_function (demux->sinkpad, GST_DEBUG_FUNCPTR (gst_hls_demux_chain)); gst_pad_set_event_function (demux->sinkpad, GST_DEBUG_FUNCPTR (gst_hls_demux_sink_event)); gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad); /* demux pad */ demux->srcpad = gst_pad_new_from_static_template (&srctemplate, "src"); gst_pad_set_event_function (demux->srcpad, GST_DEBUG_FUNCPTR (gst_hls_demux_src_event)); gst_pad_set_query_function (demux->srcpad, GST_DEBUG_FUNCPTR (gst_hls_demux_src_query)); gst_pad_set_element_private (demux->srcpad, demux); gst_element_add_pad (GST_ELEMENT (demux), demux->srcpad); /* fetcher pad */ demux->fetcherpad = gst_pad_new_from_static_template (&fetchertemplate, "sink"); gst_pad_set_chain_function (demux->fetcherpad, GST_DEBUG_FUNCPTR (gst_hls_demux_fetcher_chain)); gst_pad_set_event_function (demux->fetcherpad, GST_DEBUG_FUNCPTR (gst_hls_demux_fetcher_sink_event)); gst_pad_set_element_private (demux->fetcherpad, demux); gst_pad_activate_push (demux->fetcherpad, TRUE); /* Properties */ demux->fragments_cache = DEFAULT_FRAGMENTS_CACHE; demux->bitrate_switch_tol = DEFAULT_BITRATE_SWITCH_TOLERANCE; demux->download = gst_adapter_new (); demux->fetcher_bus = gst_bus_new (); gst_bus_set_sync_handler (demux->fetcher_bus, gst_hls_demux_fetcher_bus_handler, demux); demux->thread_cond = g_cond_new (); demux->thread_lock = g_mutex_new (); demux->fetcher_cond = g_cond_new (); demux->fetcher_lock = g_mutex_new (); demux->queue = g_queue_new (); g_static_rec_mutex_init (&demux->task_lock); demux->task = gst_task_create ((GstTaskFunction) gst_hls_demux_loop, demux); gst_task_set_lock (demux->task, &demux->task_lock); }
static void setup_ports (GstOmxBaseFilter *self) { GOmxCore *core; OMX_PARAM_PORTDEFINITIONTYPE param; core = self->gomx; memset (¶m, 0, sizeof (param)); param.nSize = sizeof (OMX_PARAM_PORTDEFINITIONTYPE); param.nVersion.s.nVersionMajor = 1; param.nVersion.s.nVersionMinor = 1; /* Input port configuration. */ param.nPortIndex = 0; OMX_GetParameter (core->omx_handle, OMX_IndexParamPortDefinition, ¶m); self->in_port = g_omx_core_setup_port (core, ¶m); gst_pad_set_element_private (self->sinkpad, self->in_port); /* Output port configuration. */ param.nPortIndex = 1; OMX_GetParameter (core->omx_handle, OMX_IndexParamPortDefinition, ¶m); self->out_port = g_omx_core_setup_port (core, ¶m); gst_pad_set_element_private (self->srcpad, self->out_port); if (g_getenv ("OMX_ALLOCATE_ON")) { self->in_port->omx_allocate = TRUE; self->out_port->omx_allocate = TRUE; self->share_input_buffer = FALSE; self->share_output_buffer = FALSE; } else if (g_getenv ("OMX_SHARE_HACK_ON")) { self->share_input_buffer = TRUE; self->share_output_buffer = TRUE; } else if (g_getenv ("OMX_SHARE_HACK_OFF")) { self->share_input_buffer = FALSE; self->share_output_buffer = FALSE; } }
/* Create a pad for receiving RTP for the session in @name */ static GstPad * create_recv_rtp (GstRDTManager * rdtmanager, GstPadTemplate * templ, const gchar * name) { guint sessid; GstRDTManagerSession *session; /* first get the session number */ if (name == NULL || sscanf (name, "recv_rtp_sink_%u", &sessid) != 1) goto no_name; GST_DEBUG_OBJECT (rdtmanager, "finding session %d", sessid); /* get or create session */ session = find_session_by_id (rdtmanager, sessid); if (!session) { GST_DEBUG_OBJECT (rdtmanager, "creating session %d", sessid); /* create session now */ session = create_session (rdtmanager, sessid); if (session == NULL) goto create_error; } /* check if pad was requested */ if (session->recv_rtp_sink != NULL) goto existed; GST_DEBUG_OBJECT (rdtmanager, "getting RTP sink pad"); session->recv_rtp_sink = gst_pad_new_from_template (templ, name); gst_pad_set_element_private (session->recv_rtp_sink, session); gst_pad_set_event_function (session->recv_rtp_sink, gst_rdt_manager_event_rdt); gst_pad_set_chain_function (session->recv_rtp_sink, gst_rdt_manager_chain_rdt); gst_pad_set_active (session->recv_rtp_sink, TRUE); gst_element_add_pad (GST_ELEMENT_CAST (rdtmanager), session->recv_rtp_sink); return session->recv_rtp_sink; /* ERRORS */ no_name: { g_warning ("rdtmanager: invalid name given"); return NULL; } create_error: { /* create_session already warned */ return NULL; } existed: { g_warning ("rdtmanager: recv_rtp pad already requested for session %d", sessid); return NULL; } }
static void setup_ports (GstOmxBaseFilter2 *self) { OMX_PARAM_PORTDEFINITIONTYPE param; int i; gboolean omx_allocate, share_buffer; gboolean set_omx_allocate = FALSE, set_share_buffer = FALSE; if (g_getenv ("OMX_ALLOCATE_ON")) { GST_DEBUG_OBJECT (self, "OMX_ALLOCATE_ON"); omx_allocate = TRUE; share_buffer = FALSE; set_omx_allocate = set_share_buffer = TRUE; } else if (g_getenv ("OMX_SHARE_HACK_ON")) { GST_DEBUG_OBJECT (self, "OMX_SHARE_HACK_ON"); share_buffer = TRUE; set_share_buffer = TRUE; } else if (g_getenv ("OMX_SHARE_HACK_OFF")) { GST_DEBUG_OBJECT (self, "OMX_SHARE_HACK_OFF"); share_buffer = FALSE; set_share_buffer = TRUE; } /* Input port configuration. */ G_OMX_PORT_GET_DEFINITION (self->in_port, ¶m); g_omx_port_setup (self->in_port, ¶m); gst_pad_set_element_private (self->sinkpad, self->in_port); if (set_omx_allocate) self->in_port->omx_allocate = omx_allocate; if (set_share_buffer) self->in_port->share_buffer = share_buffer; /* Output port configuration. */ for (i = 0; i < NUM_OUTPUTS; i++) { G_OMX_PORT_GET_DEFINITION (self->out_port[i], ¶m); g_omx_port_setup (self->out_port[i], ¶m); gst_pad_set_element_private (self->srcpad[i], self->out_port[i]); if (set_omx_allocate) self->out_port[i]->omx_allocate = omx_allocate; if (set_share_buffer) self->out_port[i]->share_buffer = share_buffer; } }
static void link_sinks (GstElement * mpegtsmux, GstPad ** src1, GstPad ** src2, GstPad ** src3, TestData * test_data) { GstPad *mux_sink1, *mux_sink2, *mux_sink3; GstCaps *caps; /* link 3 sink pads, 2 video 1 audio */ *src1 = gst_pad_new_from_static_template (&video_src_template, "src1"); gst_pad_set_active (*src1, TRUE); gst_pad_set_element_private (*src1, test_data); gst_pad_set_event_function (*src1, src_event); mux_sink1 = gst_element_get_request_pad (mpegtsmux, "sink_1"); fail_unless (gst_pad_link (*src1, mux_sink1) == GST_PAD_LINK_OK); *src2 = gst_pad_new_from_static_template (&video_src_template, "src2"); gst_pad_set_active (*src2, TRUE); gst_pad_set_element_private (*src2, test_data); gst_pad_set_event_function (*src2, src_event); mux_sink2 = gst_element_get_request_pad (mpegtsmux, "sink_2"); fail_unless (gst_pad_link (*src2, mux_sink2) == GST_PAD_LINK_OK); *src3 = gst_pad_new_from_static_template (&audio_src_template, "src3"); gst_pad_set_active (*src3, TRUE); gst_pad_set_element_private (*src3, test_data); gst_pad_set_event_function (*src3, src_event); mux_sink3 = gst_element_get_request_pad (mpegtsmux, "sink_3"); fail_unless (gst_pad_link (*src3, mux_sink3) == GST_PAD_LINK_OK); caps = gst_caps_new_simple ("video/x-h264", NULL); gst_pad_set_caps (mux_sink1, caps); gst_pad_set_caps (mux_sink2, caps); gst_caps_unref (caps); caps = gst_caps_new_simple ("audio/mpeg", "mpegversion", G_TYPE_INT, 4, NULL); gst_pad_set_caps (mux_sink3, caps); gst_caps_unref (caps); gst_object_unref (mux_sink1); gst_object_unref (mux_sink2); gst_object_unref (mux_sink3); }
static void link_src (GstElement * mpegtsmux, GstPad ** sink, TestData * test_data) { GstPad *mux_src; mux_src = gst_element_get_static_pad (mpegtsmux, "src"); *sink = gst_pad_new_from_static_template (&sink_template, "sink"); gst_pad_set_active (*sink, TRUE); gst_pad_set_event_function (*sink, sink_event); gst_pad_set_element_private (*sink, test_data); fail_unless (gst_pad_link (mux_src, *sink) == GST_PAD_LINK_OK); gst_object_unref (mux_src); }
/* Create a pad for receiving RTCP for the session in @name */ static GstPad * create_recv_rtcp (GstRTPDec * rtpdec, GstPadTemplate * templ, const gchar * name) { guint sessid; GstRTPDecSession *session; /* first get the session number */ if (name == NULL || sscanf (name, "recv_rtcp_sink_%u", &sessid) != 1) goto no_name; GST_DEBUG_OBJECT (rtpdec, "finding session %d", sessid); /* get the session, it must exist or we error */ session = find_session_by_id (rtpdec, sessid); if (!session) goto no_session; /* check if pad was requested */ if (session->recv_rtcp_sink != NULL) goto existed; GST_DEBUG_OBJECT (rtpdec, "getting RTCP sink pad"); session->recv_rtcp_sink = gst_pad_new_from_template (templ, name); gst_pad_set_element_private (session->recv_rtp_sink, session); gst_pad_set_chain_function (session->recv_rtcp_sink, gst_rtp_dec_chain_rtcp); gst_pad_set_active (session->recv_rtcp_sink, TRUE); gst_element_add_pad (GST_ELEMENT_CAST (rtpdec), session->recv_rtcp_sink); return session->recv_rtcp_sink; /* ERRORS */ no_name: { g_warning ("rtpdec: invalid name given"); return NULL; } no_session: { g_warning ("rtpdec: no session with id %d", sessid); return NULL; } existed: { g_warning ("rtpdec: recv_rtcp pad already requested for session %d", sessid); return NULL; } }
static void gst_uri_downloader_init (GstUriDownloader * downloader) { downloader->pad = gst_pad_new_from_static_template (&sink_template, "sink"); gst_pad_set_chain_function (downloader->pad, GST_DEBUG_FUNCPTR (gst_uri_downloader_chain)); gst_pad_set_event_function (downloader->pad, GST_DEBUG_FUNCPTR (gst_uri_downloader_sink_event)); gst_pad_set_element_private (downloader->pad, downloader); downloader->bus = gst_bus_new (); g_mutex_init (&downloader->download_lock); g_cond_init (&downloader->cond); }
static void gst_rtp_mux_release_pad (GstElement * element, GstPad * pad) { GstRTPMuxPadPrivate *padpriv; GST_OBJECT_LOCK (element); padpriv = gst_pad_get_element_private (pad); gst_pad_set_element_private (pad, NULL); GST_OBJECT_UNLOCK (element); gst_element_remove_pad (element, pad); if (padpriv) { g_slice_free (GstRTPMuxPadPrivate, padpriv); } }
/** * gst_collect_pads_add_pad_full: * @pads: the collectspads to use * @pad: the pad to add * @size: the size of the returned #GstCollectData structure * @destroy_notify: function to be called before the returned #GstCollectData * structure is freed * * Add a pad to the collection of collect pads. The pad has to be * a sinkpad. The refcount of the pad is incremented. Use * gst_collect_pads_remove_pad() to remove the pad from the collection * again. * * You specify a size for the returned #GstCollectData structure * so that you can use it to store additional information. * * You can also specify a #GstCollectDataDestroyNotify that will be called * just before the #GstCollectData structure is freed. It is passed the * pointer to the structure and should free any custom memory and resources * allocated for it. * * The pad will be automatically activated in push mode when @pads is * started. * * Since: 0.10.12 * * Returns: a new #GstCollectData to identify the new pad. Or NULL * if wrong parameters are supplied. * * MT safe. */ GstCollectData * gst_collect_pads_add_pad_full (GstCollectPads * pads, GstPad * pad, guint size, GstCollectDataDestroyNotify destroy_notify) { GstCollectData *data; g_return_val_if_fail (pads != NULL, NULL); g_return_val_if_fail (GST_IS_COLLECT_PADS (pads), NULL); g_return_val_if_fail (pad != NULL, NULL); g_return_val_if_fail (GST_PAD_IS_SINK (pad), NULL); g_return_val_if_fail (size >= sizeof (GstCollectData), NULL); GST_DEBUG ("adding pad %s:%s", GST_DEBUG_PAD_NAME (pad)); data = g_malloc0 (size); data->collect = pads; data->pad = gst_object_ref (pad); data->buffer = NULL; data->pos = 0; gst_segment_init (&data->segment, GST_FORMAT_UNDEFINED); data->abidata.ABI.flushing = FALSE; data->abidata.ABI.new_segment = FALSE; data->abidata.ABI.eos = FALSE; data->abidata.ABI.refcount = 1; /* FIXME: Ugly hack as we can't add more fields to GstCollectData */ g_object_set_data (G_OBJECT (pad), "gst-collect-data-destroy-notify", (void *) destroy_notify); GST_COLLECT_PADS_PAD_LOCK (pads); GST_OBJECT_LOCK (pad); gst_pad_set_element_private (pad, data); GST_OBJECT_UNLOCK (pad); pads->abidata.ABI.pad_list = g_slist_append (pads->abidata.ABI.pad_list, data); gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_collect_pads_chain)); gst_pad_set_event_function (pad, GST_DEBUG_FUNCPTR (gst_collect_pads_event)); /* activate the pad when needed */ if (pads->started) gst_pad_set_active (pad, TRUE); pads->abidata.ABI.pad_cookie++; GST_COLLECT_PADS_PAD_UNLOCK (pads); return data; }
static GstPad * gst_multipart_mux_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * req_name) { GstMultipartMux *multipart_mux; GstPad *newpad; GstElementClass *klass = GST_ELEMENT_GET_CLASS (element); gchar *name; if (templ != gst_element_class_get_pad_template (klass, "sink_%d")) goto wrong_template; multipart_mux = GST_MULTIPART_MUX (element); /* create new pad with the name */ name = g_strdup_printf ("sink_%02d", multipart_mux->numpads); newpad = gst_pad_new_from_template (templ, name); g_free (name); /* construct our own wrapper data structure for the pad to * keep track of its status */ { GstMultipartPadData *multipartpad; multipartpad = (GstMultipartPadData *) gst_collect_pads_add_pad (multipart_mux->collect, newpad, sizeof (GstMultipartPadData)); /* save a pointer to our data in the pad */ gst_pad_set_element_private (newpad, multipartpad); multipart_mux->numpads++; } /* add the pad to the element */ gst_element_add_pad (element, newpad); return newpad; /* ERRORS */ wrong_template: { g_warning ("multipart_mux: this is not our template!"); return NULL; } }
static void gst_live_adder_release_pad (GstElement * element, GstPad * pad) { GstLiveAdder *adder; GstLiveAdderPadPrivate *padprivate; adder = GST_LIVE_ADDER (element); GST_DEBUG_OBJECT (adder, "release pad %s:%s", GST_DEBUG_PAD_NAME (pad)); GST_OBJECT_LOCK (element); padprivate = gst_pad_get_element_private (pad); gst_pad_set_element_private (pad, NULL); adder->sinkpads = g_list_remove_all (adder->sinkpads, pad); GST_OBJECT_UNLOCK (element); g_free (padprivate); gst_element_remove_pad (element, pad); }
static void setup_ports (GstOmxBaseSink *self) { GOmxCore *core; OMX_PARAM_PORTDEFINITIONTYPE param; core = self->gomx; memset (¶m, 0, sizeof (param)); param.nSize = sizeof (OMX_PARAM_PORTDEFINITIONTYPE); param.nVersion.s.nVersionMajor = 1; param.nVersion.s.nVersionMinor = 1; /* Input port configuration. */ param.nPortIndex = 0; OMX_GetParameter (core->omx_handle, OMX_IndexParamPortDefinition, ¶m); self->in_port = g_omx_core_setup_port (core, ¶m); gst_pad_set_element_private (self->sinkpad, self->in_port); }
static MpegTSParsePad * mpegts_parse_create_tspad (MpegTSParse2 * parse, const gchar * pad_name) { GstPad *pad; MpegTSParsePad *tspad; pad = gst_pad_new_from_static_template (&program_template, pad_name); gst_pad_set_query_function (pad, GST_DEBUG_FUNCPTR (mpegts_parse_src_pad_query)); /* create our wrapper */ tspad = g_new0 (MpegTSParsePad, 1); tspad->pad = pad; tspad->program_number = -1; tspad->program = NULL; tspad->pushed = FALSE; tspad->flow_return = GST_FLOW_NOT_LINKED; gst_pad_set_element_private (pad, tspad); return tspad; }
static void switch_pads (GstHLSDemux * demux, GstCaps * newcaps) { GstPad *oldpad = demux->srcpad; GST_DEBUG ("Switching pads (oldpad:%p)", oldpad); /* FIXME: This is a workaround for a bug in playsink. * If we're switching from an audio-only or video-only fragment * to an audio-video segment, the new sink doesn't know about * the current running time and audio/video will go out of sync. * * This should be fixed in playsink by distributing the * current running time to newly created sinks and is * fixed in 0.11 with the new segments. */ if (demux->srcpad) gst_pad_push_event (demux->srcpad, gst_event_new_flush_stop ()); /* First create and activate new pad */ demux->srcpad = gst_pad_new_from_static_template (&srctemplate, NULL); gst_pad_set_event_function (demux->srcpad, GST_DEBUG_FUNCPTR (gst_hls_demux_src_event)); gst_pad_set_query_function (demux->srcpad, GST_DEBUG_FUNCPTR (gst_hls_demux_src_query)); gst_pad_set_element_private (demux->srcpad, demux); gst_pad_set_active (demux->srcpad, TRUE); gst_pad_set_caps (demux->srcpad, newcaps); gst_element_add_pad (GST_ELEMENT (demux), demux->srcpad); gst_element_no_more_pads (GST_ELEMENT (demux)); if (oldpad) { /* Push out EOS */ gst_pad_push_event (oldpad, gst_event_new_eos ()); gst_pad_set_active (oldpad, FALSE); gst_element_remove_pad (GST_ELEMENT (demux), oldpad); } }
static gboolean gst_mve_add_stream (GstMveDemux * mve, GstMveDemuxStream * stream, GstTagList * list) { GstPadTemplate *templ; gboolean ret = FALSE; if (stream->pad == NULL) { if (stream == mve->video_stream) { templ = gst_static_pad_template_get (&vidsrc_template); stream->pad = gst_pad_new_from_template (templ, "video"); } else { templ = gst_static_pad_template_get (&audsrc_template); stream->pad = gst_pad_new_from_template (templ, "audio"); } gst_object_unref (templ); gst_pad_set_query_type_function (stream->pad, GST_DEBUG_FUNCPTR (gst_mve_demux_get_src_query_types)); gst_pad_set_query_function (stream->pad, GST_DEBUG_FUNCPTR (gst_mve_demux_handle_src_query)); gst_pad_set_event_function (stream->pad, GST_DEBUG_FUNCPTR (gst_mve_demux_handle_src_event)); gst_pad_set_element_private (stream->pad, stream); GST_DEBUG_OBJECT (mve, "adding pad %s", GST_PAD_NAME (stream->pad)); gst_pad_set_active (stream->pad, TRUE); gst_element_add_pad (GST_ELEMENT (mve), stream->pad); ret = TRUE; } GST_DEBUG_OBJECT (mve, "setting caps %" GST_PTR_FORMAT, stream->caps); gst_pad_set_caps (stream->pad, stream->caps); if (list) gst_element_found_tags_for_pad (GST_ELEMENT (mve), stream->pad, list); return ret; }
static void gst_uri_downloader_init (GstUriDownloader * downloader) { downloader->priv = GST_URI_DOWNLOADER_GET_PRIVATE (downloader); /* Initialize the sink pad. This pad will be connected to the src pad of the * element created with gst_element_make_from_uri and will handle the download */ downloader->priv->pad = gst_pad_new_from_static_template (&sinkpadtemplate, "sink"); gst_pad_set_chain_function (downloader->priv->pad, GST_DEBUG_FUNCPTR (gst_uri_downloader_chain)); gst_pad_set_event_function (downloader->priv->pad, GST_DEBUG_FUNCPTR (gst_uri_downloader_sink_event)); gst_pad_set_element_private (downloader->priv->pad, downloader); gst_pad_set_active (downloader->priv->pad, TRUE); /* Create a bus to handle error and warning message from the source element */ downloader->priv->bus = gst_bus_new (); g_mutex_init (&downloader->priv->download_lock); g_cond_init (&downloader->priv->cond); }
static void gst_mpeg_demux_init_stream (GstMPEGDemux * mpeg_demux, gint type, GstMPEGStream * str, gint number, const gchar * name, GstPadTemplate * temp) { str->type = type; str->number = number; str->pad = CLASS (mpeg_demux)->new_output_pad (mpeg_demux, name, temp); gst_pad_set_element_private (str->pad, str); if (mpeg_demux->index) { str->index_id = _demux_get_writer_id (mpeg_demux->index, str->pad); } str->cur_ts = 0; str->scr_offs = 0; str->last_flow = GST_FLOW_OK; str->buffers_sent = 0; str->tags = NULL; }
static void gst_rtp_mux_setup_sinkpad (GstRTPMux * rtp_mux, GstPad * sinkpad) { GstRTPMuxPadPrivate *padpriv = g_slice_new0 (GstRTPMuxPadPrivate); /* setup some pad functions */ gst_pad_set_chain_function (sinkpad, GST_DEBUG_FUNCPTR (gst_rtp_mux_chain)); gst_pad_set_chain_list_function (sinkpad, GST_DEBUG_FUNCPTR (gst_rtp_mux_chain_list)); gst_pad_set_event_function (sinkpad, GST_DEBUG_FUNCPTR (gst_rtp_mux_sink_event)); gst_pad_set_query_function (sinkpad, GST_DEBUG_FUNCPTR (gst_rtp_mux_sink_query)); gst_segment_init (&padpriv->segment, GST_FORMAT_UNDEFINED); gst_pad_set_element_private (sinkpad, padpriv); gst_pad_set_active (sinkpad, TRUE); gst_element_add_pad (GST_ELEMENT (rtp_mux), sinkpad); }
static void unlink_sinkpad_cb (GstPad * pad, GstPad * peer, gpointer user_data) { KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (user_data); gchar *id = NULL; GstElement *appsrc; KMS_ELEMENT_LOCK (KMS_ELEMENT (self)); id = gst_pad_get_name (pad); GST_OBJECT_LOCK (pad); appsrc = gst_pad_get_element_private (pad); gst_pad_set_element_private (pad, NULL); if (appsrc) { g_object_unref (appsrc); } GST_OBJECT_UNLOCK (pad); if (self->priv->stopping) { GST_DEBUG_OBJECT (self, "Stop operation is pending"); self->priv->pending_pads = g_slist_prepend (self->priv->pending_pads, g_strdup (id)); goto end; } if (kms_base_media_muxer_remove_src (self->priv->mux, id)) { g_hash_table_remove (self->priv->srcs, id); } end: KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self)); g_free (id); }
static gboolean activate_session (GstRDTManager * rdtmanager, GstRDTManagerSession * session, guint32 ssrc, guint8 pt) { GstPadTemplate *templ; GstElementClass *klass; gchar *name; GstCaps *caps; GValue ret = { 0 }; GValue args[3] = { {0} , {0} , {0} }; GST_DEBUG_OBJECT (rdtmanager, "creating stream"); session->ssrc = ssrc; session->pt = pt; /* get pt map */ g_value_init (&args[0], GST_TYPE_ELEMENT); g_value_set_object (&args[0], rdtmanager); g_value_init (&args[1], G_TYPE_UINT); g_value_set_uint (&args[1], session->id); g_value_init (&args[2], G_TYPE_UINT); g_value_set_uint (&args[2], pt); g_value_init (&ret, GST_TYPE_CAPS); g_value_set_boxed (&ret, NULL); g_signal_emitv (args, gst_rdt_manager_signals[SIGNAL_REQUEST_PT_MAP], 0, &ret); g_value_unset (&args[0]); g_value_unset (&args[1]); g_value_unset (&args[2]); caps = (GstCaps *) g_value_dup_boxed (&ret); g_value_unset (&ret); if (caps) gst_rdt_manager_parse_caps (rdtmanager, session, caps); name = g_strdup_printf ("recv_rtp_src_%u_%u_%u", session->id, ssrc, pt); klass = GST_ELEMENT_GET_CLASS (rdtmanager); templ = gst_element_class_get_pad_template (klass, "recv_rtp_src_%u_%u_%u"); session->recv_rtp_src = gst_pad_new_from_template (templ, name); g_free (name); gst_pad_set_element_private (session->recv_rtp_src, session); gst_pad_set_query_function (session->recv_rtp_src, gst_rdt_manager_query_src); gst_pad_set_activatemode_function (session->recv_rtp_src, gst_rdt_manager_src_activate_mode); gst_pad_set_active (session->recv_rtp_src, TRUE); gst_pad_set_caps (session->recv_rtp_src, caps); gst_caps_unref (caps); gst_element_add_pad (GST_ELEMENT_CAST (rdtmanager), session->recv_rtp_src); return TRUE; }