static void gst_wrapper_camera_bin_src_init (GstWrapperCameraBinSrc * self, GstWrapperCameraBinSrcClass * klass) { self->vfsrc = gst_ghost_pad_new_no_target (GST_BASE_CAMERA_SRC_VIEWFINDER_PAD_NAME, GST_PAD_SRC); gst_element_add_pad (GST_ELEMENT (self), self->vfsrc); self->imgsrc = gst_ghost_pad_new_no_target (GST_BASE_CAMERA_SRC_IMAGE_PAD_NAME, GST_PAD_SRC); gst_element_add_pad (GST_ELEMENT (self), self->imgsrc); self->vidsrc = gst_ghost_pad_new_no_target (GST_BASE_CAMERA_SRC_VIDEO_PAD_NAME, GST_PAD_SRC); gst_element_add_pad (GST_ELEMENT (self), self->vidsrc); self->srcpad_event_func = GST_PAD_EVENTFUNC (self->vfsrc); gst_pad_set_event_function (self->imgsrc, gst_wrapper_camera_bin_src_event); gst_pad_set_event_function (self->vidsrc, gst_wrapper_camera_bin_src_event); gst_pad_set_event_function (self->vfsrc, gst_wrapper_camera_bin_src_event); /* TODO where are variables reset? */ self->image_capture_count = 0; self->video_rec_status = GST_VIDEO_RECORDING_STATUS_DONE; self->video_renegotiate = FALSE; self->image_renegotiate = FALSE; self->mode = GST_BASE_CAMERA_SRC_CAST (self)->mode; }
static gboolean gst_a2dp_sink_init_ghost_pad(GstA2dpSink *self) { GstPad *capsfilter_pad; /* we search for the capsfilter sinkpad */ capsfilter_pad = gst_element_get_static_pad(self->capsfilter, "sink"); /* now we add a ghostpad */ self->ghostpad = GST_GHOST_PAD(gst_ghost_pad_new("sink", capsfilter_pad)); g_object_unref(capsfilter_pad); /* the getcaps of our ghostpad must reflect the device caps */ gst_pad_set_getcaps_function(GST_PAD(self->ghostpad), gst_a2dp_sink_get_caps); self->ghostpad_setcapsfunc = GST_PAD_SETCAPSFUNC(self->ghostpad); gst_pad_set_setcaps_function(GST_PAD(self->ghostpad), GST_DEBUG_FUNCPTR(gst_a2dp_sink_set_caps)); /* we need to handle events on our own and we also need the eventfunc * of the ghostpad for forwarding calls */ self->ghostpad_eventfunc = GST_PAD_EVENTFUNC(GST_PAD(self->ghostpad)); gst_pad_set_event_function(GST_PAD(self->ghostpad), gst_a2dp_sink_handle_event); if (!gst_element_add_pad(GST_ELEMENT(self), GST_PAD(self->ghostpad))) GST_ERROR_OBJECT(self, "failed to add ghostpad"); return TRUE; }
void kms_utils_set_pad_event_function_full (GstPad * pad, GstPadEventFunction event, gpointer user_data, GDestroyNotify notify, gboolean chain_callbacks) { GstPadEventFunction prev_func; KmsEventData *data; /* Create new data */ data = g_slice_new0 (KmsEventData); data->user_func = event; data->user_data = user_data; data->user_notify = notify; if (!chain_callbacks) { goto set_func; } prev_func = GST_PAD_EVENTFUNC (pad); if (prev_func != kms_event_function) { /* Keep first data to chain to it */ KmsEventData *first; first = g_slice_new0 (KmsEventData); first->user_func = GST_PAD_EVENTFUNC (pad); first->user_data = pad->eventdata; first->user_notify = pad->eventnotify; data->next = first; } else { /* Point to previous data to be chained */ data->next = pad->eventdata; } /* Do not destroy previous data when set_event is called */ pad->eventnotify = NULL; pad->eventdata = NULL; set_func: gst_pad_set_event_function_full (pad, kms_event_function, data, kms_event_data_destroy); }
static GstPad * gst_mxf_mux_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * pad_name) { GstMXFMux *mux = GST_MXF_MUX (element); GstMXFMuxPad *cpad; GstPad *pad = NULL; guint pad_number; gchar *name = NULL; const MXFEssenceElementWriter *writer; if (mux->state != GST_MXF_MUX_STATE_HEADER) { GST_WARNING_OBJECT (mux, "Can't request pads after writing header"); return NULL; } writer = mxf_essence_element_writer_find (templ); if (!writer) { GST_ERROR_OBJECT (mux, "Not our template"); return NULL; } pad_number = g_atomic_int_exchange_and_add ((gint *) & mux->n_pads, 1); name = gst_mxf_mux_create_pad_name (templ, pad_number); GST_DEBUG_OBJECT (mux, "Creating pad '%s'", name); pad = gst_pad_new_from_template (templ, name); g_free (name); cpad = (GstMXFMuxPad *) gst_collect_pads_add_pad (mux->collect, pad, sizeof (GstMXFMuxPad)); cpad->last_timestamp = 0; cpad->adapter = gst_adapter_new (); cpad->writer = writer; /* FIXME: hacked way to override/extend the event function of * GstCollectPads; because it sets its own event function giving the * element no access to events. */ mux->collect_event = (GstPadEventFunction) GST_PAD_EVENTFUNC (pad); gst_pad_set_event_function (pad, GST_DEBUG_FUNCPTR (gst_mxf_mux_handle_sink_event)); gst_pad_set_setcaps_function (pad, gst_mxf_mux_setcaps); gst_pad_use_fixed_caps (pad); gst_pad_set_active (pad, TRUE); gst_element_add_pad (element, pad); return pad; }
static void gst_frei0r_mixer_init (GstFrei0rMixer * self, GstFrei0rMixerClass * klass) { self->property_cache = gst_frei0r_property_cache_init (klass->properties, klass->n_properties); gst_video_info_init (&self->info); self->collect = gst_collect_pads_new (); gst_collect_pads_set_function (self->collect, (GstCollectPadsFunction) gst_frei0r_mixer_collected, self); gst_collect_pads_set_event_function (self->collect, (GstCollectPadsEventFunction) gst_frei0r_mixer_sink_event, self); gst_collect_pads_set_query_function (self->collect, (GstCollectPadsQueryFunction) gst_frei0r_mixer_sink_query, self); self->src = gst_pad_new_from_template (gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "src"), "src"); gst_pad_set_query_function (self->src, GST_DEBUG_FUNCPTR (gst_frei0r_mixer_src_query)); gst_pad_set_event_function (self->src, GST_DEBUG_FUNCPTR (gst_frei0r_mixer_src_event)); gst_element_add_pad (GST_ELEMENT_CAST (self), self->src); self->sink0 = gst_pad_new_from_template (gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink_0"), "sink_0"); gst_collect_pads_add_pad (self->collect, self->sink0, sizeof (GstCollectData), NULL, TRUE); self->collect_event = (GstPadEventFunction) GST_PAD_EVENTFUNC (self->sink0); gst_element_add_pad (GST_ELEMENT_CAST (self), self->sink0); self->sink1 = gst_pad_new_from_template (gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink_1"), "sink_1"); gst_collect_pads_add_pad (self->collect, self->sink1, sizeof (GstCollectData), NULL, TRUE); gst_element_add_pad (GST_ELEMENT_CAST (self), self->sink1); if (klass->info->plugin_type == F0R_PLUGIN_TYPE_MIXER3) { self->sink2 = gst_pad_new_from_template (gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink_2"), "sink_2"); gst_collect_pads_add_pad (self->collect, self->sink2, sizeof (GstCollectData), NULL, TRUE); gst_element_add_pad (GST_ELEMENT_CAST (self), self->sink2); } }
static void gst_aspect_ratio_crop_init (GstAspectRatioCrop * aspect_ratio_crop) { GstPad *link_pad; GstPad *src_pad; GST_DEBUG_CATEGORY_INIT (aspect_ratio_crop_debug, "aspectratiocrop", 0, "aspectratiocrop"); aspect_ratio_crop->ar_num = 0; aspect_ratio_crop->ar_denom = 1; g_mutex_init (&aspect_ratio_crop->crop_lock); /* add the transform element */ aspect_ratio_crop->videocrop = gst_element_factory_make ("videocrop", NULL); gst_bin_add (GST_BIN (aspect_ratio_crop), aspect_ratio_crop->videocrop); /* create ghost pad src */ link_pad = gst_element_get_static_pad (GST_ELEMENT (aspect_ratio_crop->videocrop), "src"); src_pad = gst_ghost_pad_new ("src", link_pad); gst_pad_set_query_function (src_pad, GST_DEBUG_FUNCPTR (gst_aspect_ratio_crop_src_query)); gst_element_add_pad (GST_ELEMENT (aspect_ratio_crop), src_pad); gst_object_unref (link_pad); /* create ghost pad sink */ link_pad = gst_element_get_static_pad (GST_ELEMENT (aspect_ratio_crop->videocrop), "sink"); aspect_ratio_crop->sink = gst_ghost_pad_new ("sink", link_pad); gst_element_add_pad (GST_ELEMENT (aspect_ratio_crop), aspect_ratio_crop->sink); gst_object_unref (link_pad); aspect_ratio_crop->sinkpad_old_eventfunc = GST_PAD_EVENTFUNC (aspect_ratio_crop->sink); gst_pad_set_event_function (aspect_ratio_crop->sink, GST_DEBUG_FUNCPTR (gst_aspect_ratio_crop_sink_event)); }
static void gst_vp8_enc_init (GstVP8Enc * gst_vp8_enc, GstVP8EncClass * klass) { GST_DEBUG_OBJECT (gst_vp8_enc, "init"); gst_vp8_enc->bitrate = DEFAULT_BITRATE; gst_vp8_enc->mode = DEFAULT_MODE; gst_vp8_enc->quality = DEFAULT_QUALITY; gst_vp8_enc->error_resilient = DEFAULT_ERROR_RESILIENT; gst_vp8_enc->max_latency = DEFAULT_MAX_LATENCY; gst_vp8_enc->max_keyframe_distance = DEFAULT_MAX_KEYFRAME_DISTANCE; gst_vp8_enc->multipass_mode = DEFAULT_MULTIPASS_MODE; gst_vp8_enc->multipass_cache_file = DEFAULT_MULTIPASS_CACHE_FILE; gst_vp8_enc->auto_alt_ref_frames = DEFAULT_AUTO_ALT_REF_FRAMES; /* FIXME: Add sink/src event vmethods */ gst_vp8_enc->base_sink_event_func = GST_PAD_EVENTFUNC (GST_BASE_VIDEO_CODEC_SINK_PAD (gst_vp8_enc)); gst_pad_set_event_function (GST_BASE_VIDEO_CODEC_SINK_PAD (gst_vp8_enc), gst_vp8_enc_sink_event); }
static void rsn_dec_init (RsnDec * self, RsnDecClass * klass) { GstPadTemplate *templ; templ = gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink"); g_assert (templ != NULL); self->sinkpad = GST_GHOST_PAD_CAST (gst_ghost_pad_new_no_target_from_template ("sink", templ)); self->sink_event_func = GST_PAD_EVENTFUNC (self->sinkpad); gst_pad_set_event_function (GST_PAD_CAST (self->sinkpad), GST_DEBUG_FUNCPTR (rsn_dec_sink_event)); templ = gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "src"); g_assert (templ != NULL); self->srcpad = GST_GHOST_PAD_CAST (gst_ghost_pad_new_no_target_from_template ("src", templ)); gst_element_add_pad (GST_ELEMENT (self), GST_PAD_CAST (self->sinkpad)); gst_element_add_pad (GST_ELEMENT (self), GST_PAD_CAST (self->srcpad)); }
static GstPad * gst_interleave_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * req_name) { GstInterleave *self = GST_INTERLEAVE (element); GstPad *new_pad; gchar *pad_name; gint channels, padnumber; GValue val = { 0, }; if (templ->direction != GST_PAD_SINK) goto not_sink_pad; channels = g_atomic_int_exchange_and_add (&self->channels, 1); padnumber = g_atomic_int_exchange_and_add (&self->padcounter, 1); pad_name = g_strdup_printf ("sink%d", padnumber); new_pad = GST_PAD_CAST (g_object_new (GST_TYPE_INTERLEAVE_PAD, "name", pad_name, "direction", templ->direction, "template", templ, NULL)); GST_INTERLEAVE_PAD_CAST (new_pad)->channel = channels; GST_DEBUG_OBJECT (self, "requested new pad %s", pad_name); g_free (pad_name); gst_pad_set_setcaps_function (new_pad, GST_DEBUG_FUNCPTR (gst_interleave_sink_setcaps)); gst_pad_set_getcaps_function (new_pad, GST_DEBUG_FUNCPTR (gst_interleave_sink_getcaps)); gst_collect_pads_add_pad (self->collect, new_pad, sizeof (GstCollectData)); /* FIXME: hacked way to override/extend the event function of * GstCollectPads; because it sets its own event function giving the * element no access to events */ self->collect_event = (GstPadEventFunction) GST_PAD_EVENTFUNC (new_pad); gst_pad_set_event_function (new_pad, GST_DEBUG_FUNCPTR (gst_interleave_sink_event)); if (!gst_element_add_pad (element, new_pad)) goto could_not_add; g_value_init (&val, GST_TYPE_AUDIO_CHANNEL_POSITION); g_value_set_enum (&val, GST_AUDIO_CHANNEL_POSITION_NONE); self->input_channel_positions = g_value_array_append (self->input_channel_positions, &val); g_value_unset (&val); /* Update the src caps if we already have them */ if (self->sinkcaps) { GstCaps *srccaps; GstStructure *s; /* Take lock to make sure processing finishes first */ GST_OBJECT_LOCK (self->collect); srccaps = gst_caps_copy (self->sinkcaps); s = gst_caps_get_structure (srccaps, 0); gst_structure_set (s, "channels", G_TYPE_INT, self->channels, NULL); gst_interleave_set_channel_positions (self, s); gst_pad_set_caps (self->src, srccaps); gst_caps_unref (srccaps); GST_OBJECT_UNLOCK (self->collect); } return new_pad; /* errors */ not_sink_pad: { g_warning ("interleave: requested new pad that is not a SINK pad\n"); return NULL; } could_not_add: { GST_DEBUG_OBJECT (self, "could not add pad %s", GST_PAD_NAME (new_pad)); gst_collect_pads_remove_pad (self->collect, new_pad); gst_object_unref (new_pad); return NULL; } }
static GstPad * gst_ffmpegmux_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * name) { GstFFMpegMux *ffmpegmux = (GstFFMpegMux *) element; GstElementClass *klass = GST_ELEMENT_GET_CLASS (element); GstFFMpegMuxPad *collect_pad; gchar *padname; GstPad *pad; AVStream *st; enum CodecType type; gint bitrate = 0, framesize = 0; g_return_val_if_fail (templ != NULL, NULL); g_return_val_if_fail (templ->direction == GST_PAD_SINK, NULL); g_return_val_if_fail (ffmpegmux->opened == FALSE, NULL); /* figure out a name that *we* like */ if (templ == gst_element_class_get_pad_template (klass, "video_%d")) { padname = g_strdup_printf ("video_%d", ffmpegmux->videopads++); type = CODEC_TYPE_VIDEO; bitrate = 64 * 1024; framesize = 1152; } else if (templ == gst_element_class_get_pad_template (klass, "audio_%d")) { padname = g_strdup_printf ("audio_%d", ffmpegmux->audiopads++); type = CODEC_TYPE_AUDIO; bitrate = 285 * 1024; } else { g_warning ("ffmux: unknown pad template!"); return NULL; } /* create pad */ pad = gst_pad_new_from_template (templ, padname); collect_pad = (GstFFMpegMuxPad *) gst_collect_pads_add_pad (ffmpegmux->collect, pad, sizeof (GstFFMpegMuxPad)); collect_pad->padnum = ffmpegmux->context->nb_streams; /* small hack to put our own event pad function and chain up to collect pad */ ffmpegmux->event_function = GST_PAD_EVENTFUNC (pad); gst_pad_set_event_function (pad, GST_DEBUG_FUNCPTR (gst_ffmpegmux_sink_event)); gst_pad_set_setcaps_function (pad, GST_DEBUG_FUNCPTR (gst_ffmpegmux_setcaps)); gst_element_add_pad (element, pad); /* AVStream needs to be created */ st = av_new_stream (ffmpegmux->context, collect_pad->padnum); st->codec->codec_type = type; st->codec->codec_id = CODEC_ID_NONE; /* this is a check afterwards */ st->stream_copy = 1; /* we're not the actual encoder */ st->codec->bit_rate = bitrate; st->codec->frame_size = framesize; /* we fill in codec during capsnego */ /* we love debug output (c) (tm) (r) */ GST_DEBUG ("Created %s pad for ffmux_%s element", padname, ((GstFFMpegMuxClass *) klass)->in_plugin->name); g_free (padname); return pad; }
static void gst_camera_bin_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstCameraBin *camera = GST_CAMERA_BIN_CAST (object); switch (prop_id) { case PROP_MODE: gst_camera_bin_change_mode (camera, g_value_get_enum (value)); break; case PROP_LOCATION: gst_camera_bin_set_location (camera, g_value_get_string (value)); break; case PROP_CAMERA_SRC: gst_camera_bin_set_camera_src (camera, g_value_get_object (value)); break; case PROP_IMAGE_CAPTURE_CAPS:{ GstPad *pad = NULL; if (camera->src) pad = gst_element_get_static_pad (camera->src, GST_BASE_CAMERA_SRC_IMAGE_PAD_NAME); GST_DEBUG_OBJECT (camera, "Setting image capture caps to %" GST_PTR_FORMAT, gst_value_get_caps (value)); /* set the capsfilter caps and notify the src to renegotiate */ g_object_set (camera->imagebin_capsfilter, "caps", gst_value_get_caps (value), NULL); if (pad) { GST_DEBUG_OBJECT (camera, "Pushing renegotiate on %s", GST_PAD_NAME (pad)); GST_PAD_EVENTFUNC (pad) (pad, gst_camera_bin_new_event_renegotiate ()); gst_object_unref (pad); } } break; case PROP_VIDEO_CAPTURE_CAPS:{ GstPad *pad = NULL; if (camera->src) pad = gst_element_get_static_pad (camera->src, GST_BASE_CAMERA_SRC_VIDEO_PAD_NAME); GST_DEBUG_OBJECT (camera, "Setting video capture caps to %" GST_PTR_FORMAT, gst_value_get_caps (value)); /* set the capsfilter caps and notify the src to renegotiate */ g_object_set (camera->videobin_capsfilter, "caps", gst_value_get_caps (value), NULL); if (pad) { GST_DEBUG_OBJECT (camera, "Pushing renegotiate on %s", GST_PAD_NAME (pad)); GST_PAD_EVENTFUNC (pad) (pad, gst_camera_bin_new_event_renegotiate ()); gst_object_unref (pad); } } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }