static void gst_rtp_ssrc_demux_init (GstRtpSsrcDemux * demux) { GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux); demux->rtp_sink = gst_pad_new_from_template (gst_element_class_get_pad_template (klass, "sink"), "sink"); gst_pad_set_chain_function (demux->rtp_sink, gst_rtp_ssrc_demux_chain); gst_pad_set_event_function (demux->rtp_sink, gst_rtp_ssrc_demux_sink_event); gst_pad_set_iterate_internal_links_function (demux->rtp_sink, gst_rtp_ssrc_demux_iterate_internal_links_sink); gst_element_add_pad (GST_ELEMENT_CAST (demux), demux->rtp_sink); demux->rtcp_sink = gst_pad_new_from_template (gst_element_class_get_pad_template (klass, "rtcp_sink"), "rtcp_sink"); gst_pad_set_chain_function (demux->rtcp_sink, gst_rtp_ssrc_demux_rtcp_chain); gst_pad_set_event_function (demux->rtcp_sink, gst_rtp_ssrc_demux_sink_event); gst_pad_set_iterate_internal_links_function (demux->rtcp_sink, gst_rtp_ssrc_demux_iterate_internal_links_sink); gst_element_add_pad (GST_ELEMENT_CAST (demux), demux->rtcp_sink); g_rec_mutex_init (&demux->padlock); }
static void gst_cc_extractor_init (GstCCExtractor * filter) { filter->sinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink"); gst_pad_set_event_function (filter->sinkpad, GST_DEBUG_FUNCPTR (gst_cc_extractor_sink_event)); gst_pad_set_chain_function (filter->sinkpad, GST_DEBUG_FUNCPTR (gst_cc_extractor_chain)); gst_pad_set_iterate_internal_links_function (filter->sinkpad, GST_DEBUG_FUNCPTR (gst_cc_extractor_iterate_internal_links)); GST_PAD_SET_PROXY_CAPS (filter->sinkpad); GST_PAD_SET_PROXY_ALLOCATION (filter->sinkpad); GST_PAD_SET_PROXY_SCHEDULING (filter->sinkpad); filter->srcpad = gst_pad_new_from_static_template (&srctemplate, "src"); gst_pad_set_iterate_internal_links_function (filter->srcpad, GST_DEBUG_FUNCPTR (gst_cc_extractor_iterate_internal_links)); GST_PAD_SET_PROXY_CAPS (filter->srcpad); GST_PAD_SET_PROXY_ALLOCATION (filter->srcpad); GST_PAD_SET_PROXY_SCHEDULING (filter->srcpad); gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad); gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad); filter->combiner = gst_flow_combiner_new (); gst_cc_extractor_reset (filter); }
static void gst_auto_convert_init (GstAutoConvert * autoconvert) { autoconvert->sinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink"); autoconvert->srcpad = gst_pad_new_from_static_template (&srctemplate, "src"); gst_pad_set_chain_function (autoconvert->sinkpad, GST_DEBUG_FUNCPTR (gst_auto_convert_sink_chain)); gst_pad_set_chain_list_function (autoconvert->sinkpad, GST_DEBUG_FUNCPTR (gst_auto_convert_sink_chain_list)); gst_pad_set_event_function (autoconvert->sinkpad, GST_DEBUG_FUNCPTR (gst_auto_convert_sink_event)); gst_pad_set_query_function (autoconvert->sinkpad, GST_DEBUG_FUNCPTR (gst_auto_convert_sink_query)); gst_pad_set_iterate_internal_links_function (autoconvert->sinkpad, GST_DEBUG_FUNCPTR (gst_auto_convert_iterate_internal_links)); gst_pad_set_event_function (autoconvert->srcpad, GST_DEBUG_FUNCPTR (gst_auto_convert_src_event)); gst_pad_set_query_function (autoconvert->srcpad, GST_DEBUG_FUNCPTR (gst_auto_convert_src_query)); gst_pad_set_iterate_internal_links_function (autoconvert->sinkpad, GST_DEBUG_FUNCPTR (gst_auto_convert_iterate_internal_links)); gst_element_add_pad (GST_ELEMENT (autoconvert), autoconvert->sinkpad); gst_element_add_pad (GST_ELEMENT (autoconvert), autoconvert->srcpad); }
static void gst_timecodewait_init (GstTimeCodeWait * self) { self->asinkpad = gst_pad_new_from_static_template (&audio_sink_template, "asink"); gst_pad_set_chain_function (self->asinkpad, GST_DEBUG_FUNCPTR (gst_timecodewait_asink_chain)); gst_pad_set_event_function (self->asinkpad, GST_DEBUG_FUNCPTR (gst_timecodewait_asink_event)); gst_pad_set_iterate_internal_links_function (self->asinkpad, GST_DEBUG_FUNCPTR (gst_timecodewait_iterate_internal_links)); gst_element_add_pad (GST_ELEMENT (self), self->asinkpad); self->vsinkpad = gst_pad_new_from_static_template (&video_sink_template, "vsink"); gst_pad_set_chain_function (self->vsinkpad, GST_DEBUG_FUNCPTR (gst_timecodewait_vsink_chain)); gst_pad_set_event_function (self->vsinkpad, GST_DEBUG_FUNCPTR (gst_timecodewait_vsink_event)); gst_pad_set_iterate_internal_links_function (self->vsinkpad, GST_DEBUG_FUNCPTR (gst_timecodewait_iterate_internal_links)); gst_element_add_pad (GST_ELEMENT (self), self->vsinkpad); self->asrcpad = gst_pad_new_from_static_template (&audio_src_template, "asrc"); gst_pad_set_iterate_internal_links_function (self->asrcpad, GST_DEBUG_FUNCPTR (gst_timecodewait_iterate_internal_links)); gst_element_add_pad (GST_ELEMENT (self), self->asrcpad); self->vsrcpad = gst_pad_new_from_static_template (&video_src_template, "vsrc"); gst_pad_set_iterate_internal_links_function (self->vsrcpad, GST_DEBUG_FUNCPTR (gst_timecodewait_iterate_internal_links)); gst_element_add_pad (GST_ELEMENT (self), self->vsrcpad); GST_PAD_SET_PROXY_CAPS (self->asinkpad); GST_PAD_SET_PROXY_ALLOCATION (self->asinkpad); GST_PAD_SET_PROXY_CAPS (self->asrcpad); GST_PAD_SET_PROXY_SCHEDULING (self->asrcpad); GST_PAD_SET_PROXY_CAPS (self->vsinkpad); GST_PAD_SET_PROXY_ALLOCATION (self->vsinkpad); GST_PAD_SET_PROXY_CAPS (self->vsrcpad); GST_PAD_SET_PROXY_SCHEDULING (self->vsrcpad); self->running_time_of_timecode = GST_CLOCK_TIME_NONE; self->video_eos_flag = FALSE; self->audio_flush_flag = FALSE; self->shutdown_flag = FALSE; self->from_string = FALSE; self->tc = gst_video_time_code_new_empty (); g_mutex_init (&self->mutex); g_cond_init (&self->cond); }
/* 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 gst_proxy_pad_init (GstProxyPad * ppad) { GstPad *pad = (GstPad *) ppad; GST_PROXY_PAD_PRIVATE (ppad) = G_TYPE_INSTANCE_GET_PRIVATE (ppad, GST_TYPE_PROXY_PAD, GstProxyPadPrivate); GST_PROXY_GET_LOCK (pad) = g_mutex_new (); gst_pad_set_query_type_function (pad, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_query_type)); gst_pad_set_event_function (pad, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_event)); gst_pad_set_query_function (pad, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_query)); gst_pad_set_internal_link_function (pad, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_internal_link)); gst_pad_set_iterate_internal_links_function (pad, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_iterate_internal_links)); gst_pad_set_getcaps_function (pad, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_getcaps)); gst_pad_set_acceptcaps_function (pad, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_acceptcaps)); gst_pad_set_fixatecaps_function (pad, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_fixatecaps)); gst_pad_set_setcaps_function (pad, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_setcaps)); }
static GstPad * rsn_stream_selector_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * unused) { RsnStreamSelector *sel; gchar *name = NULL; GstPad *sinkpad = NULL; sel = RSN_STREAM_SELECTOR (element); g_return_val_if_fail (templ->direction == GST_PAD_SINK, NULL); GST_LOG_OBJECT (sel, "Creating new pad %d", sel->padcount); GST_OBJECT_LOCK (sel); name = g_strdup_printf ("sink%d", sel->padcount++); sinkpad = g_object_new (RSN_TYPE_SELECTOR_PAD, "name", name, "direction", templ->direction, "template", templ, NULL); g_free (name); sel->n_pads++; GST_OBJECT_UNLOCK (sel); gst_pad_set_event_function (sinkpad, GST_DEBUG_FUNCPTR (gst_selector_pad_event)); gst_pad_set_getcaps_function (sinkpad, GST_DEBUG_FUNCPTR (gst_selector_pad_getcaps)); gst_pad_set_chain_function (sinkpad, GST_DEBUG_FUNCPTR (gst_selector_pad_chain)); gst_pad_set_iterate_internal_links_function (sinkpad, GST_DEBUG_FUNCPTR (rsn_stream_selector_iterate_linked_pads)); gst_pad_set_bufferalloc_function (sinkpad, GST_DEBUG_FUNCPTR (gst_selector_pad_bufferalloc)); gst_pad_set_active (sinkpad, TRUE); gst_element_add_pad (GST_ELEMENT (sel), sinkpad); return sinkpad; }
static void gst_proxy_pad_init (GstProxyPad * ppad) { GstPad *pad = (GstPad *) ppad; GST_PROXY_PAD_PRIVATE (ppad) = gst_proxy_pad_get_instance_private (ppad); gst_pad_set_iterate_internal_links_function (pad, gst_proxy_pad_iterate_internal_links_default); GST_PAD_SET_PROXY_CAPS (pad); GST_PAD_SET_PROXY_SCHEDULING (pad); GST_PAD_SET_PROXY_ALLOCATION (pad); }
static void rsn_stream_selector_init (RsnStreamSelector * sel) { sel->srcpad = gst_pad_new ("src", GST_PAD_SRC); gst_pad_set_iterate_internal_links_function (sel->srcpad, GST_DEBUG_FUNCPTR (rsn_stream_selector_iterate_linked_pads)); gst_pad_set_getcaps_function (sel->srcpad, GST_DEBUG_FUNCPTR (rsn_stream_selector_getcaps)); gst_element_add_pad (GST_ELEMENT (sel), sel->srcpad); /* sinkpad management */ sel->padcount = 0; sel->active_sinkpad = NULL; gst_segment_init (&sel->segment, GST_FORMAT_UNDEFINED); }
static void gst_proxy_pad_init (GstProxyPad * ppad) { GstPad *pad = (GstPad *) ppad; GST_PROXY_PAD_PRIVATE (ppad) = G_TYPE_INSTANCE_GET_PRIVATE (ppad, GST_TYPE_PROXY_PAD, GstProxyPadPrivate); gst_pad_set_iterate_internal_links_function (pad, gst_proxy_pad_iterate_internal_links_default); GST_PAD_SET_PROXY_CAPS (pad); GST_PAD_SET_PROXY_SCHEDULING (pad); GST_PAD_SET_PROXY_ALLOCATION (pad); }
static void gst_input_selector_init (GstInputSelector * sel) { sel->srcpad = gst_pad_new ("src", GST_PAD_SRC); gst_pad_set_iterate_internal_links_function (sel->srcpad, GST_DEBUG_FUNCPTR (gst_selector_pad_iterate_linked_pads)); gst_pad_set_getcaps_function (sel->srcpad, GST_DEBUG_FUNCPTR (gst_input_selector_getcaps)); gst_pad_set_query_function (sel->srcpad, GST_DEBUG_FUNCPTR (gst_input_selector_query)); gst_pad_set_event_function (sel->srcpad, GST_DEBUG_FUNCPTR (gst_input_selector_event)); gst_element_add_pad (GST_ELEMENT (sel), sel->srcpad); /* sinkpad management */ sel->active_sinkpad = NULL; sel->padcount = 0; gst_segment_init (&sel->segment, GST_FORMAT_UNDEFINED); sel->lock = g_mutex_new (); sel->cond = g_cond_new (); sel->blocked = FALSE; sel->select_all = FALSE; }
static void gst_decklink_sink_init (GstDecklinkSink * decklinksink, GstDecklinkSinkClass * decklinksink_class) { decklinksink->videosinkpad = gst_pad_new_from_static_template (&gst_decklink_sink_videosink_template, "sink"); gst_pad_set_getcaps_function (decklinksink->videosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_getcaps)); gst_pad_set_setcaps_function (decklinksink->videosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_setcaps)); gst_pad_set_acceptcaps_function (decklinksink->videosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_acceptcaps)); gst_pad_set_activate_function (decklinksink->videosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_activate)); gst_pad_set_activatepush_function (decklinksink->videosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_activatepush)); gst_pad_set_activatepull_function (decklinksink->videosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_activatepull)); gst_pad_set_link_function (decklinksink->videosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_link)); gst_pad_set_chain_function (decklinksink->videosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_chain)); gst_pad_set_chain_list_function (decklinksink->videosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_chainlist)); gst_pad_set_event_function (decklinksink->videosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_event)); gst_pad_set_query_function (decklinksink->videosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_query)); gst_pad_set_bufferalloc_function (decklinksink->videosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_bufferalloc)); gst_pad_set_iterate_internal_links_function (decklinksink->videosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_iterintlink)); gst_element_add_pad (GST_ELEMENT (decklinksink), decklinksink->videosinkpad); decklinksink->audiosinkpad = gst_pad_new_from_static_template (&gst_decklink_sink_audiosink_template, "audiosink"); gst_pad_set_getcaps_function (decklinksink->audiosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_getcaps)); gst_pad_set_setcaps_function (decklinksink->audiosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_setcaps)); gst_pad_set_acceptcaps_function (decklinksink->audiosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_acceptcaps)); gst_pad_set_activate_function (decklinksink->audiosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_activate)); gst_pad_set_activatepush_function (decklinksink->audiosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_activatepush)); gst_pad_set_activatepull_function (decklinksink->audiosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_activatepull)); gst_pad_set_link_function (decklinksink->audiosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_link)); gst_pad_set_chain_function (decklinksink->audiosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_chain)); gst_pad_set_chain_list_function (decklinksink->audiosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_chainlist)); gst_pad_set_event_function (decklinksink->audiosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_event)); gst_pad_set_query_function (decklinksink->audiosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_query)); gst_pad_set_bufferalloc_function (decklinksink->audiosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_bufferalloc)); gst_pad_set_iterate_internal_links_function (decklinksink->audiosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_iterintlink)); gst_element_add_pad (GST_ELEMENT (decklinksink), decklinksink->audiosinkpad); decklinksink->cond = g_cond_new (); decklinksink->mutex = g_mutex_new (); decklinksink->audio_mutex = g_mutex_new (); decklinksink->mode = GST_DECKLINK_MODE_NTSC; decklinksink->callback = new Output; decklinksink->callback->decklinksink = decklinksink; #ifdef _MSC_VER decklinksink->com_init_lock = g_mutex_new(); decklinksink->com_deinit_lock = g_mutex_new(); decklinksink->com_initialized = g_cond_new(); decklinksink->com_uninitialize = g_cond_new(); decklinksink->com_uninitialized = g_cond_new(); g_mutex_lock (decklinksink->com_init_lock); /* create the COM initialization thread */ g_thread_create ((GThreadFunc)gst_decklink_sink_com_thread, decklinksink, FALSE, NULL); /* wait until the COM thread signals that COM has been initialized */ g_cond_wait (decklinksink->com_initialized, decklinksink->com_init_lock); g_mutex_unlock (decklinksink->com_init_lock); #endif /* _MSC_VER */ }
static GstFlowReturn gst_cc_extractor_handle_meta (GstCCExtractor * filter, GstBuffer * buf, GstVideoCaptionMeta * meta) { GstBuffer *outbuf = NULL; GstEvent *event; gchar *captionid; GstFlowReturn flow; GST_DEBUG_OBJECT (filter, "Handling meta"); /* Check if the meta type matches the configured one */ if (filter->captionpad != NULL && meta->caption_type != filter->caption_type) { GST_ERROR_OBJECT (filter, "GstVideoCaptionMeta type changed, Not handled currently"); flow = GST_FLOW_NOT_NEGOTIATED; goto out; } if (filter->captionpad == NULL) { GstCaps *caption_caps = NULL; GstEvent *stream_event; GST_DEBUG_OBJECT (filter, "Creating new caption pad"); switch (meta->caption_type) { case GST_VIDEO_CAPTION_TYPE_CEA608_RAW: caption_caps = gst_caps_from_string ("closedcaption/x-cea-608,format=(string)raw"); break; case GST_VIDEO_CAPTION_TYPE_CEA608_IN_CEA708_RAW: caption_caps = gst_caps_from_string ("closedcaption/x-cea-608,format=(string)cc_data"); break; case GST_VIDEO_CAPTION_TYPE_CEA708_RAW: caption_caps = gst_caps_from_string ("closedcaption/x-cea-708,format=(string)cc_data"); break; case GST_VIDEO_CAPTION_TYPE_CEA708_CDP: caption_caps = gst_caps_from_string ("closedcaption/x-cea-708,format=(string)cdp"); break; default: break; } if (caption_caps == NULL) { GST_ERROR_OBJECT (filter, "Unknown/invalid caption type"); return GST_FLOW_NOT_NEGOTIATED; } /* Create the caption pad and set the caps */ filter->captionpad = gst_pad_new_from_static_template (&captiontemplate, "caption"); gst_pad_set_iterate_internal_links_function (filter->sinkpad, GST_DEBUG_FUNCPTR (gst_cc_extractor_iterate_internal_links)); gst_pad_set_active (filter->captionpad, TRUE); gst_element_add_pad (GST_ELEMENT (filter), filter->captionpad); gst_flow_combiner_add_pad (filter->combiner, filter->captionpad); captionid = gst_pad_create_stream_id (filter->captionpad, (GstElement *) filter, "caption"); stream_event = gst_event_new_stream_start (captionid); g_free (captionid); /* FIXME : Create a proper stream-id */ if ((event = gst_pad_get_sticky_event (filter->srcpad, GST_EVENT_STREAM_START, 0))) { guint group_id; if (gst_event_parse_group_id (event, &group_id)) gst_event_set_group_id (stream_event, group_id); gst_event_unref (event); } gst_pad_push_event (filter->captionpad, stream_event); gst_pad_set_caps (filter->captionpad, caption_caps); gst_caps_unref (caption_caps); /* Carry over sticky events */ if ((event = gst_pad_get_sticky_event (filter->srcpad, GST_EVENT_SEGMENT, 0))) gst_pad_push_event (filter->captionpad, event); if ((event = gst_pad_get_sticky_event (filter->srcpad, GST_EVENT_TAG, 0))) gst_pad_push_event (filter->captionpad, event); filter->caption_type = meta->caption_type; } GST_DEBUG_OBJECT (filter, "Creating new buffer of size %" G_GSIZE_FORMAT " bytes", meta->size); /* Extract caption data into new buffer with identical buffer timestamps */ outbuf = gst_buffer_new_allocate (NULL, meta->size, NULL); gst_buffer_fill (outbuf, 0, meta->data, meta->size); GST_BUFFER_PTS (outbuf) = GST_BUFFER_PTS (buf); GST_BUFFER_DTS (outbuf) = GST_BUFFER_DTS (buf); GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf); /* We don't really care about the flow return */ flow = gst_pad_push (filter->captionpad, outbuf); out: /* Set flow return on pad and return combined value */ return gst_flow_combiner_update_pad_flow (filter->combiner, filter->captionpad, flow); }
static GstPad * find_or_create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc, PadType padtype) { GstPad *rtp_pad, *rtcp_pad; GstElementClass *klass; GstPadTemplate *templ; gchar *padname; GstRtpSsrcDemuxPad *demuxpad; GstPad *retpad; gulong rtp_block, rtcp_block; GST_PAD_LOCK (demux); demuxpad = find_demux_pad_for_ssrc (demux, ssrc); if (demuxpad != NULL) { gboolean forward = FALSE; switch (padtype) { case RTP_PAD: retpad = gst_object_ref (demuxpad->rtp_pad); if (!demuxpad->pushed_initial_rtp_events) { forward = TRUE; demuxpad->pushed_initial_rtp_events = TRUE; } break; case RTCP_PAD: retpad = gst_object_ref (demuxpad->rtcp_pad); if (!demuxpad->pushed_initial_rtcp_events) { forward = TRUE; demuxpad->pushed_initial_rtcp_events = TRUE; } break; default: retpad = NULL; g_assert_not_reached (); } GST_PAD_UNLOCK (demux); if (forward) forward_initial_events (demux, ssrc, retpad, padtype); return retpad; } GST_DEBUG_OBJECT (demux, "creating new pad for SSRC %08x", ssrc); klass = GST_ELEMENT_GET_CLASS (demux); templ = gst_element_class_get_pad_template (klass, "src_%u"); padname = g_strdup_printf ("src_%u", ssrc); rtp_pad = gst_pad_new_from_template (templ, padname); g_free (padname); templ = gst_element_class_get_pad_template (klass, "rtcp_src_%u"); padname = g_strdup_printf ("rtcp_src_%u", ssrc); rtcp_pad = gst_pad_new_from_template (templ, padname); g_free (padname); /* wrap in structure and add to list */ demuxpad = g_new0 (GstRtpSsrcDemuxPad, 1); demuxpad->ssrc = ssrc; demuxpad->rtp_pad = rtp_pad; demuxpad->rtcp_pad = rtcp_pad; gst_pad_set_element_private (rtp_pad, demuxpad); gst_pad_set_element_private (rtcp_pad, demuxpad); demux->srcpads = g_slist_prepend (demux->srcpads, demuxpad); gst_pad_set_query_function (rtp_pad, gst_rtp_ssrc_demux_src_query); gst_pad_set_iterate_internal_links_function (rtp_pad, gst_rtp_ssrc_demux_iterate_internal_links_src); gst_pad_set_event_function (rtp_pad, gst_rtp_ssrc_demux_src_event); gst_pad_use_fixed_caps (rtp_pad); gst_pad_set_active (rtp_pad, TRUE); gst_pad_set_event_function (rtcp_pad, gst_rtp_ssrc_demux_src_event); gst_pad_set_iterate_internal_links_function (rtcp_pad, gst_rtp_ssrc_demux_iterate_internal_links_src); gst_pad_use_fixed_caps (rtcp_pad); gst_pad_set_active (rtcp_pad, TRUE); if (padtype == RTP_PAD) { demuxpad->pushed_initial_rtp_events = TRUE; forward_initial_events (demux, ssrc, rtp_pad, padtype); } else if (padtype == RTCP_PAD) { demuxpad->pushed_initial_rtcp_events = TRUE; forward_initial_events (demux, ssrc, rtcp_pad, padtype); } else { g_assert_not_reached (); } gst_element_add_pad (GST_ELEMENT_CAST (demux), rtp_pad); gst_element_add_pad (GST_ELEMENT_CAST (demux), rtcp_pad); switch (padtype) { case RTP_PAD: retpad = gst_object_ref (demuxpad->rtp_pad); break; case RTCP_PAD: retpad = gst_object_ref (demuxpad->rtcp_pad); break; default: retpad = NULL; g_assert_not_reached (); } gst_object_ref (rtp_pad); gst_object_ref (rtcp_pad); rtp_block = gst_pad_add_probe (rtp_pad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, NULL, NULL, NULL); rtcp_block = gst_pad_add_probe (rtcp_pad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, NULL, NULL, NULL); GST_PAD_UNLOCK (demux); g_signal_emit (G_OBJECT (demux), gst_rtp_ssrc_demux_signals[SIGNAL_NEW_SSRC_PAD], 0, ssrc, rtp_pad); gst_pad_remove_probe (rtp_pad, rtp_block); gst_pad_remove_probe (rtcp_pad, rtcp_block); gst_object_unref (rtp_pad); gst_object_unref (rtcp_pad); return retpad; }
/* GstElement vfuncs */ static GstPad * gst_stream_synchronizer_request_new_pad (GstElement * element, GstPadTemplate * temp, const gchar * name, const GstCaps * caps) { GstStreamSynchronizer *self = GST_STREAM_SYNCHRONIZER (element); GstStream *stream; gchar *tmp; GST_STREAM_SYNCHRONIZER_LOCK (self); GST_DEBUG_OBJECT (self, "Requesting new pad for stream %d", self->current_stream_number); stream = g_slice_new0 (GstStream); stream->transform = self; stream->stream_number = self->current_stream_number; g_cond_init (&stream->stream_finish_cond); stream->stream_start_seqnum = G_MAXUINT32; stream->segment_seqnum = G_MAXUINT32; tmp = g_strdup_printf ("sink_%u", self->current_stream_number); stream->sinkpad = gst_pad_new_from_static_template (&sinktemplate, tmp); g_free (tmp); gst_pad_set_element_private (stream->sinkpad, stream); gst_pad_set_iterate_internal_links_function (stream->sinkpad, GST_DEBUG_FUNCPTR (gst_stream_synchronizer_iterate_internal_links)); gst_pad_set_query_function (stream->sinkpad, GST_DEBUG_FUNCPTR (gst_stream_synchronizer_query)); gst_pad_set_event_function (stream->sinkpad, GST_DEBUG_FUNCPTR (gst_stream_synchronizer_sink_event)); gst_pad_set_chain_function (stream->sinkpad, GST_DEBUG_FUNCPTR (gst_stream_synchronizer_sink_chain)); tmp = g_strdup_printf ("src_%u", self->current_stream_number); stream->srcpad = gst_pad_new_from_static_template (&srctemplate, tmp); g_free (tmp); gst_pad_set_element_private (stream->srcpad, stream); gst_pad_set_iterate_internal_links_function (stream->srcpad, GST_DEBUG_FUNCPTR (gst_stream_synchronizer_iterate_internal_links)); gst_pad_set_query_function (stream->srcpad, GST_DEBUG_FUNCPTR (gst_stream_synchronizer_query)); gst_pad_set_event_function (stream->srcpad, GST_DEBUG_FUNCPTR (gst_stream_synchronizer_src_event)); gst_segment_init (&stream->segment, GST_FORMAT_UNDEFINED); self->streams = g_list_prepend (self->streams, stream); self->current_stream_number++; GST_STREAM_SYNCHRONIZER_UNLOCK (self); /* Add pads and activate unless we're going to NULL */ g_rec_mutex_lock (GST_STATE_GET_LOCK (self)); if (GST_STATE_TARGET (self) != GST_STATE_NULL) { gst_pad_set_active (stream->srcpad, TRUE); gst_pad_set_active (stream->sinkpad, TRUE); } gst_element_add_pad (GST_ELEMENT_CAST (self), stream->srcpad); gst_element_add_pad (GST_ELEMENT_CAST (self), stream->sinkpad); g_rec_mutex_unlock (GST_STATE_GET_LOCK (self)); return stream->sinkpad; }
static void gst_decklink_src_init (GstDecklinkSrc * decklinksrc, GstDecklinkSrcClass * decklinksrc_class) { g_static_rec_mutex_init (&decklinksrc->task_mutex); decklinksrc->task = gst_task_create (gst_decklink_src_task, decklinksrc); gst_task_set_lock (decklinksrc->task, &decklinksrc->task_mutex); decklinksrc->audiosrcpad = gst_pad_new_from_static_template (&gst_decklink_src_audio_src_template, "audiosrc"); gst_pad_set_getcaps_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_getcaps)); gst_pad_set_setcaps_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_setcaps)); gst_pad_set_acceptcaps_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_acceptcaps)); gst_pad_set_fixatecaps_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_fixatecaps)); gst_pad_set_activate_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_activate)); gst_pad_set_activatepush_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_activatepush)); gst_pad_set_activatepull_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_activatepull)); gst_pad_set_link_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_link)); gst_pad_set_getrange_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_getrange)); gst_pad_set_event_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_event)); gst_pad_set_query_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_query)); gst_pad_set_iterate_internal_links_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_iterintlink)); gst_element_add_pad (GST_ELEMENT (decklinksrc), decklinksrc->audiosrcpad); decklinksrc->videosrcpad = gst_pad_new_from_template (gst_element_class_get_pad_template (GST_ELEMENT_CLASS (decklinksrc_class), "videosrc"), "videosrc"); gst_pad_set_getcaps_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_getcaps)); gst_pad_set_setcaps_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_setcaps)); gst_pad_set_acceptcaps_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_acceptcaps)); gst_pad_set_fixatecaps_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_fixatecaps)); gst_pad_set_activate_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_activate)); gst_pad_set_activatepush_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_activatepush)); gst_pad_set_activatepull_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_activatepull)); gst_pad_set_link_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_link)); gst_pad_set_getrange_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_getrange)); gst_pad_set_event_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_event)); gst_pad_set_query_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_query)); gst_pad_set_iterate_internal_links_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_iterintlink)); gst_element_add_pad (GST_ELEMENT (decklinksrc), decklinksrc->videosrcpad); decklinksrc->cond = g_cond_new (); decklinksrc->mutex = g_mutex_new (); decklinksrc->copy_data = TRUE; decklinksrc->mode = GST_DECKLINK_MODE_NTSC; decklinksrc->connection = GST_DECKLINK_CONNECTION_SDI; decklinksrc->audio_connection = GST_DECKLINK_AUDIO_CONNECTION_AUTO; decklinksrc->subdevice = 0; decklinksrc->stop = FALSE; decklinksrc->dropped_frames = 0; decklinksrc->dropped_frames_old = 0; decklinksrc->frame_num = -1; /* -1 so will be 0 after incrementing */ #ifdef _MSC_VER decklinksrc->com_init_lock = g_mutex_new(); decklinksrc->com_deinit_lock = g_mutex_new(); decklinksrc->com_initialized = g_cond_new(); decklinksrc->com_uninitialize = g_cond_new(); decklinksrc->com_uninitialized = g_cond_new(); g_mutex_lock (decklinksrc->com_init_lock); /* create the COM initialization thread */ g_thread_create ((GThreadFunc)gst_decklink_src_com_thread, decklinksrc, FALSE, NULL); /* wait until the COM thread signals that COM has been initialized */ g_cond_wait (decklinksrc->com_initialized, decklinksrc->com_init_lock); g_mutex_unlock (decklinksrc->com_init_lock); #endif /* _MSC_VER */ }
/* with PAD_LOCK */ static GstRtpSsrcDemuxPad * create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc, GstClockTime timestamp) { GstPad *rtp_pad, *rtcp_pad; GstElementClass *klass; GstPadTemplate *templ; gchar *padname; GstRtpSsrcDemuxPad *demuxpad; GST_DEBUG_OBJECT (demux, "creating pad for SSRC %08x", ssrc); klass = GST_ELEMENT_GET_CLASS (demux); templ = gst_element_class_get_pad_template (klass, "src_%d"); padname = g_strdup_printf ("src_%d", ssrc); rtp_pad = gst_pad_new_from_template (templ, padname); g_free (padname); templ = gst_element_class_get_pad_template (klass, "rtcp_src_%d"); padname = g_strdup_printf ("rtcp_src_%d", ssrc); rtcp_pad = gst_pad_new_from_template (templ, padname); g_free (padname); /* we use the first timestamp received to calculate the difference between * timestamps on all streams */ GST_DEBUG_OBJECT (demux, "SSRC %08x, first timestamp %" GST_TIME_FORMAT, ssrc, GST_TIME_ARGS (timestamp)); /* wrap in structure and add to list */ demuxpad = g_new0 (GstRtpSsrcDemuxPad, 1); demuxpad->ssrc = ssrc; demuxpad->rtp_pad = rtp_pad; demuxpad->rtcp_pad = rtcp_pad; GST_DEBUG_OBJECT (demux, "first timestamp %" GST_TIME_FORMAT, GST_TIME_ARGS (timestamp)); gst_pad_set_element_private (rtp_pad, demuxpad); gst_pad_set_element_private (rtcp_pad, demuxpad); demux->srcpads = g_slist_prepend (demux->srcpads, demuxpad); /* copy caps from input */ gst_pad_set_caps (rtp_pad, GST_PAD_CAPS (demux->rtp_sink)); gst_pad_use_fixed_caps (rtp_pad); gst_pad_set_caps (rtcp_pad, GST_PAD_CAPS (demux->rtcp_sink)); gst_pad_use_fixed_caps (rtcp_pad); gst_pad_set_event_function (rtp_pad, gst_rtp_ssrc_demux_src_event); gst_pad_set_query_function (rtp_pad, gst_rtp_ssrc_demux_src_query); gst_pad_set_iterate_internal_links_function (rtp_pad, gst_rtp_ssrc_demux_iterate_internal_links); gst_pad_set_active (rtp_pad, TRUE); gst_pad_set_event_function (rtcp_pad, gst_rtp_ssrc_demux_src_event); gst_pad_set_iterate_internal_links_function (rtcp_pad, gst_rtp_ssrc_demux_iterate_internal_links); gst_pad_set_active (rtcp_pad, TRUE); gst_element_add_pad (GST_ELEMENT_CAST (demux), rtp_pad); gst_element_add_pad (GST_ELEMENT_CAST (demux), rtcp_pad); g_signal_emit (G_OBJECT (demux), gst_rtp_ssrc_demux_signals[SIGNAL_NEW_SSRC_PAD], 0, ssrc, rtp_pad); return demuxpad; }
/* with PAD_LOCK */ static GstRtpSsrcDemuxPad * find_or_create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc) { GstPad *rtp_pad, *rtcp_pad; GstElementClass *klass; GstPadTemplate *templ; gchar *padname; GstRtpSsrcDemuxPad *demuxpad; GstCaps *caps; struct ForwardEventData fdata; GST_DEBUG_OBJECT (demux, "creating pad for SSRC %08x", ssrc); demuxpad = find_demux_pad_for_ssrc (demux, ssrc); if (demuxpad != NULL) { return demuxpad; } klass = GST_ELEMENT_GET_CLASS (demux); templ = gst_element_class_get_pad_template (klass, "src_%u"); padname = g_strdup_printf ("src_%u", ssrc); rtp_pad = gst_pad_new_from_template (templ, padname); g_free (padname); templ = gst_element_class_get_pad_template (klass, "rtcp_src_%u"); padname = g_strdup_printf ("rtcp_src_%u", ssrc); rtcp_pad = gst_pad_new_from_template (templ, padname); g_free (padname); /* wrap in structure and add to list */ demuxpad = g_new0 (GstRtpSsrcDemuxPad, 1); demuxpad->ssrc = ssrc; demuxpad->rtp_pad = rtp_pad; demuxpad->rtcp_pad = rtcp_pad; fdata.ssrc = ssrc; gst_pad_set_element_private (rtp_pad, demuxpad); gst_pad_set_element_private (rtcp_pad, demuxpad); demux->srcpads = g_slist_prepend (demux->srcpads, demuxpad); gst_pad_set_query_function (rtp_pad, gst_rtp_ssrc_demux_src_query); gst_pad_set_iterate_internal_links_function (rtp_pad, gst_rtp_ssrc_demux_iterate_internal_links_src); gst_pad_set_event_function (rtp_pad, gst_rtp_ssrc_demux_src_event); gst_pad_use_fixed_caps (rtp_pad); gst_pad_set_active (rtp_pad, TRUE); fdata.pad = rtp_pad; gst_pad_sticky_events_foreach (demux->rtp_sink, forward_sticky_events, &fdata); gst_pad_set_event_function (rtcp_pad, gst_rtp_ssrc_demux_src_event); gst_pad_set_iterate_internal_links_function (rtcp_pad, gst_rtp_ssrc_demux_iterate_internal_links_src); gst_pad_use_fixed_caps (rtcp_pad); gst_pad_set_active (rtcp_pad, TRUE); fdata.pad = rtcp_pad; gst_pad_sticky_events_foreach (demux->rtcp_sink, forward_sticky_events, &fdata); /* copy caps from input */ if ((caps = gst_pad_get_current_caps (demux->rtp_sink))) { gst_pad_set_caps (rtp_pad, caps); gst_caps_unref (caps); } if ((caps = gst_pad_get_current_caps (demux->rtcp_sink))) { gst_pad_set_caps (rtcp_pad, caps); gst_caps_unref (caps); } gst_element_add_pad (GST_ELEMENT_CAST (demux), rtp_pad); gst_element_add_pad (GST_ELEMENT_CAST (demux), rtcp_pad); g_signal_emit (G_OBJECT (demux), gst_rtp_ssrc_demux_signals[SIGNAL_NEW_SSRC_PAD], 0, ssrc, rtp_pad); return demuxpad; }
static void gst_videoframe_audiolevel_init (GstVideoFrameAudioLevel * self) { self->asinkpad = gst_pad_new_from_static_template (&audio_sink_template, "asink"); gst_pad_set_chain_function (self->asinkpad, GST_DEBUG_FUNCPTR (gst_videoframe_audiolevel_asink_chain)); gst_pad_set_event_function (self->asinkpad, GST_DEBUG_FUNCPTR (gst_videoframe_audiolevel_asink_event)); gst_pad_set_iterate_internal_links_function (self->asinkpad, GST_DEBUG_FUNCPTR (gst_videoframe_audiolevel_iterate_internal_links)); gst_element_add_pad (GST_ELEMENT (self), self->asinkpad); self->vsinkpad = gst_pad_new_from_static_template (&video_sink_template, "vsink"); gst_pad_set_chain_function (self->vsinkpad, GST_DEBUG_FUNCPTR (gst_videoframe_audiolevel_vsink_chain)); gst_pad_set_event_function (self->vsinkpad, GST_DEBUG_FUNCPTR (gst_videoframe_audiolevel_vsink_event)); gst_pad_set_iterate_internal_links_function (self->vsinkpad, GST_DEBUG_FUNCPTR (gst_videoframe_audiolevel_iterate_internal_links)); gst_element_add_pad (GST_ELEMENT (self), self->vsinkpad); self->asrcpad = gst_pad_new_from_static_template (&audio_src_template, "asrc"); gst_pad_set_iterate_internal_links_function (self->asrcpad, GST_DEBUG_FUNCPTR (gst_videoframe_audiolevel_iterate_internal_links)); gst_element_add_pad (GST_ELEMENT (self), self->asrcpad); self->vsrcpad = gst_pad_new_from_static_template (&video_src_template, "vsrc"); gst_pad_set_iterate_internal_links_function (self->vsrcpad, GST_DEBUG_FUNCPTR (gst_videoframe_audiolevel_iterate_internal_links)); gst_element_add_pad (GST_ELEMENT (self), self->vsrcpad); GST_PAD_SET_PROXY_CAPS (self->asinkpad); GST_PAD_SET_PROXY_ALLOCATION (self->asinkpad); GST_PAD_SET_PROXY_CAPS (self->asrcpad); GST_PAD_SET_PROXY_SCHEDULING (self->asrcpad); GST_PAD_SET_PROXY_CAPS (self->vsinkpad); GST_PAD_SET_PROXY_ALLOCATION (self->vsinkpad); GST_PAD_SET_PROXY_CAPS (self->vsrcpad); GST_PAD_SET_PROXY_SCHEDULING (self->vsrcpad); self->adapter = gst_adapter_new (); g_queue_init (&self->vtimeq); self->first_time = GST_CLOCK_TIME_NONE; self->total_frames = 0; /* alignment_threshold and discont_wait should become properties if needed */ self->alignment_threshold = 40 * GST_MSECOND; self->discont_time = GST_CLOCK_TIME_NONE; self->next_offset = -1; self->discont_wait = 1 * GST_SECOND; self->video_eos_flag = FALSE; self->audio_flush_flag = FALSE; self->shutdown_flag = FALSE; g_mutex_init (&self->mutex); g_cond_init (&self->cond); }