//FIXME this should be part of the library void shmdata_base_reader_clean_element (GstElement *element) { if (element != NULL && GST_IS_ELEMENT(element) && GST_STATE_CHANGE_FAILURE != GST_STATE_RETURN(element)) { { // unlinking pads GstIterator *pad_iter = gst_element_iterate_pads(element); gst_iterator_foreach(pad_iter, (GFunc) shmdata_base_reader_unlink_pad, NULL); gst_iterator_free(pad_iter); } { // releasing request pads GstIterator *pad_iter = gst_element_iterate_pads(element); gst_iterator_foreach(pad_iter, (GFunc) shmdata_base_reader_release_request_pad, element); gst_iterator_free(pad_iter); } GstState state = GST_STATE_TARGET(element); if (state != GST_STATE_NULL) { if (GST_STATE_CHANGE_ASYNC == gst_element_set_state(element, GST_STATE_NULL)) { while (GST_STATE(element) != GST_STATE_NULL) { // warning this may be blocking gst_element_get_state(element, NULL, NULL, GST_CLOCK_TIME_NONE); } } } if (GST_IS_BIN(gst_element_get_parent(element))) gst_bin_remove(GST_BIN(gst_element_get_parent(element)), element); else gst_object_unref(element); } }
static gboolean remove_adder (GstElement * adder) { KmsAudioMixer *self; self = (KmsAudioMixer *) gst_element_get_parent (adder); if (self == NULL) { GST_WARNING_OBJECT (adder, "No parent element"); return FALSE; } GST_DEBUG ("Removing element %" GST_PTR_FORMAT, adder); kms_audio_mixer_remove_sometimes_src_pad (self, adder); gst_object_ref (adder); gst_element_set_locked_state (adder, TRUE); gst_element_set_state (adder, GST_STATE_NULL); gst_bin_remove (GST_BIN (self), adder); gst_object_unref (adder); gst_object_unref (self); return G_SOURCE_REMOVE; }
/* used for catching newsegment events while we don't have a sink, for * later forwarding it to the sink */ static gboolean gst_a2dp_sink_handle_event(GstPad *pad, GstEvent *event) { GstA2dpSink *self; GstTagList *taglist = NULL; GstObject *parent; self = GST_A2DP_SINK(GST_PAD_PARENT(pad)); parent = gst_element_get_parent(GST_ELEMENT(self->sink)); if (GST_EVENT_TYPE(event) == GST_EVENT_NEWSEGMENT && parent != GST_OBJECT_CAST(self)) { if (self->newseg_event != NULL) gst_event_unref(self->newseg_event); self->newseg_event = gst_event_ref(event); } else if (GST_EVENT_TYPE(event) == GST_EVENT_TAG && parent != GST_OBJECT_CAST(self)) { if (self->taglist == NULL) gst_event_parse_tag(event, &self->taglist); else { gst_event_parse_tag(event, &taglist); gst_tag_list_insert(self->taglist, taglist, GST_TAG_MERGE_REPLACE); } } if (parent != NULL) gst_object_unref(GST_OBJECT(parent)); return self->ghostpad_eventfunc(GST_PAD(self->ghostpad), event); }
void gst_insert_bin_remove (GstInsertBin * self, GstElement * element, GstInsertBinCallback callback, gpointer user_data) { GstObject *parent; g_return_if_fail (GST_IS_ELEMENT (element)); parent = gst_element_get_parent (element); if (parent) { gboolean is_parent; is_parent = (parent == GST_OBJECT_CAST (self)); gst_object_unref (parent); if (!is_parent) { if (callback) callback (self, element, FALSE, user_data); return; } } else { GList *item; struct ChangeData *data = NULL; GST_OBJECT_LOCK (self); for (item = self->priv->change_queue.head; item; item = item->next) { data = item->data; if (data->element == element) { if (data->action == GST_INSERT_BIN_ACTION_ADD) g_queue_delete_link (&self->priv->change_queue, item); break; } data = NULL; } GST_OBJECT_UNLOCK (self); if (data) { gst_object_ref (element); gst_insert_bin_change_data_complete (self, data, TRUE); if (callback) callback (self, element, TRUE, user_data); gst_object_unref (element); } else { if (callback) callback (self, element, FALSE, user_data); } return; } gst_object_ref (element); gst_insert_bin_add_operation (self, element, GST_INSERT_BIN_ACTION_REMOVE, NULL, FALSE, callback, user_data); }
void start_dccpclientsrc_pipe (GstElement * object, gint socket, gpointer data) { GstElement *dccpclientsrc = (GstElement *) data; g_object_set (G_OBJECT (dccpclientsrc), "sockfd", socket, NULL); g_print ("Setting pipelinesrc to PLAYING\n"); GstElement *pipelinesrc = (GstElement *) gst_element_get_parent (dccpclientsrc); gst_element_set_state (pipelinesrc, GST_STATE_PLAYING); }
void start_dccpserversink_pipe (GstElement * object, gint socket, gpointer data) { GstElement *dccpserversink = (GstElement *) data; g_object_set (G_OBJECT (dccpserversink), "sockfd", socket, NULL); g_print ("Setting pipelinesink to PLAYING\n"); GstElement *pipelinesink = (GstElement *) gst_element_get_parent (dccpserversink); gst_element_set_state (pipelinesink, GST_STATE_PLAYING); gst_object_unref (pipelinesink); }
static void on_pad_added (GstElement * src, GstPad * pad, gpointer data) { GstElement *fakesink = gst_element_factory_make ("fakesink", NULL); GstPad *sinkpad = gst_element_get_static_pad (fakesink, "sink"); GstElement *bin = (GstElement *) gst_element_get_parent (src); gst_bin_add (GST_BIN (bin), fakesink); gst_pad_link (pad, sinkpad); gst_object_unref (sinkpad); gst_object_unref (bin); }
static void really_remove_filter (GstPad *pad, gboolean blocked, RBGstPipelineOp *op) { GstPad *mypad; GstPad *prevpad, *nextpad; GstElement *bin; /* get the containing bin and remove it */ bin = GST_ELEMENT (gst_element_get_parent (op->element)); if (bin == NULL) { return; } rb_debug ("removing filter %p", op->element); _rb_player_gst_filter_emit_filter_pre_remove (RB_PLAYER_GST_FILTER (op->player), op->element); /* probably check return? */ gst_element_set_state (bin, GST_STATE_NULL); /* unlink our sink */ mypad = gst_element_get_static_pad (bin, "sink"); prevpad = gst_pad_get_peer (mypad); gst_pad_unlink (prevpad, mypad); gst_object_unref (mypad); /* unlink our src */ mypad = gst_element_get_static_pad (bin, "src"); nextpad = gst_pad_get_peer (mypad); gst_pad_unlink (mypad, nextpad); gst_object_unref (mypad); /* link previous and next pads */ gst_pad_link (prevpad, nextpad); gst_object_unref (prevpad); gst_object_unref (nextpad); gst_bin_remove (GST_BIN (op->fixture), bin); gst_object_unref (bin); /* if we're supposed to be playing, unblock the sink */ if (blocked) { rb_debug ("unblocking pad after removing filter"); gst_pad_set_blocked_async (pad, FALSE, (GstPadBlockCallback)pipeline_op_done, NULL); } free_pipeline_op (op); }
static void kms_send_data_add_bus_watcher (KmsSendData * self) { GstElement *parent; parent = GST_ELEMENT (gst_element_get_parent (GST_ELEMENT (self))); self->priv->bus = gst_pipeline_get_bus (GST_PIPELINE (GST_BIN (parent))); self->priv->handler_id = g_signal_connect (G_OBJECT (self->priv->bus), "message", G_CALLBACK (code_received_cb), self); gst_object_unref (parent); }
static void add_element_used (InsanityGstPipelineTest * ptest, GstElement * element) { GstElementFactory *factory; const char *factory_name; char label[32], *element_name; GValue string_value = { 0 }; GstElement *parent; /* Only add once */ element_name = gst_element_get_name (element); if (g_hash_table_lookup_extended (ptest->priv->elements_used, element_name, NULL, NULL)) { g_free (element_name); return; } g_hash_table_insert (ptest->priv->elements_used, g_strdup (element_name), NULL); ptest->priv->element_count++; g_value_init (&string_value, G_TYPE_STRING); factory = gst_element_get_factory (element); factory_name = factory ? gst_element_factory_get_metadata (factory, GST_ELEMENT_METADATA_LONGNAME) : "(no factory)"; g_value_take_string (&string_value, element_name); snprintf (label, sizeof (label), "elements-used.%u.name", ptest->priv->element_count); insanity_test_set_extra_info (INSANITY_TEST (ptest), label, &string_value); g_value_reset (&string_value); g_value_set_string (&string_value, factory_name); snprintf (label, sizeof (label), "elements-used.%u.factory", ptest->priv->element_count); insanity_test_set_extra_info (INSANITY_TEST (ptest), label, &string_value); g_value_reset (&string_value); parent = GST_ELEMENT (gst_element_get_parent (element)); if (parent) { g_value_take_string (&string_value, gst_element_get_name (parent)); snprintf (label, sizeof (label), "elements-used.%u.parent", ptest->priv->element_count); insanity_test_set_extra_info (INSANITY_TEST (ptest), label, &string_value); g_value_reset (&string_value); gst_object_unref (parent); } }
void GstUtils::clean_element(GstElement *element) { if (nullptr == element) return; if (!GST_IS_ELEMENT(element)) { g_warning("%s failed (not a gst element)", __FUNCTION__); return; } if (GST_STATE_CHANGE_FAILURE == GST_STATE_RETURN(element)) { g_warning("%s failed (state error)", __FUNCTION__); return; } // if (GST_IS_BIN(element)) // g_debug("%d, %d, %d, state return %d", GST_STATE(element), // GST_STATE_TARGET(element), GST_STATE_PENDING(element), // GST_STATE_RETURN(element)); // FIXME { // unlinking pads // GstIterator *pad_iter; // pad_iter = gst_element_iterate_pads(element); // gst_iterator_foreach(pad_iter, (GFunc) GstUtils::unlink_pad, nullptr); // gst_iterator_free(pad_iter); // } // FIXME { // releasing request pads // GstIterator *pad_iter; // pad_iter = gst_element_iterate_pads(element); // gst_iterator_foreach(pad_iter, (GFunc) GstUtils::release_request_pad, element); // gst_iterator_free(pad_iter); // } // GstState state = GST_STATE_TARGET(element); // if (state != GST_STATE_NULL) { // if (GST_STATE_CHANGE_ASYNC == // gst_element_set_state(element, GST_STATE_NULL)) { // while (GST_STATE(element) != GST_STATE_NULL) { // // warning this may be blocking // gst_element_get_state(element, nullptr, nullptr, // GST_CLOCK_TIME_NONE); // } // } // } // if (GST_IS_BIN(gst_element_get_parent(element))) // gst_bin_remove(GST_BIN(gst_element_get_parent(element)), element); // else if (!GST_IS_BIN(gst_element_get_parent(element)) && ((GObject *) element)->ref_count > 0) gst_object_unref(element); }
GST_END_TEST static gboolean remove_audiotestsrc (GstElement * audiotestsrc) { GstElement *pipeline = GST_ELEMENT (gst_element_get_parent (audiotestsrc)); gst_object_ref (audiotestsrc); gst_element_set_locked_state (audiotestsrc, TRUE); gst_element_set_state (audiotestsrc, GST_STATE_NULL); if (!gst_bin_remove (GST_BIN (pipeline), audiotestsrc)) GST_ERROR ("Can not remove %" GST_PTR_FORMAT, audiotestsrc); gst_object_unref (pipeline); gst_object_unref (audiotestsrc); return G_SOURCE_REMOVE; }
static void dbin_pad_added_cb (GstElement * dbin, GstPad * pad, gpointer user_data G_GNUC_UNUSED) { GstPad *srcpad; GstSingleDecodeBin *sdbin = GST_SINGLE_DECODE_BIN (gst_element_get_parent (dbin)); if (sdbin->connected) { GST_WARNING_OBJECT (sdbin, "Ignoring new decodebin pad"); return; } srcpad = gst_element_get_static_pad (GST_ELEMENT (sdbin), "src"); gst_ghost_pad_set_target (GST_GHOST_PAD (srcpad), pad); gst_object_unref (srcpad); sdbin->connected = TRUE; sdbin->parse_only = DEFAULT_PARSE_ONLY; }
static void fakesink_dtls_server_hand_off (GstElement * fakesink, GstBuffer * buf, GstPad * pad, gpointer loop) { GstElement *pipeline = GST_ELEMENT (gst_element_get_parent (fakesink)); GST_INFO_OBJECT (fakesink, "BUF received"); G_LOCK (check_receive_lock); if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (pipeline), CLIENT_RECEIVES))) { g_object_set (G_OBJECT (fakesink), "signal-handoffs", FALSE, NULL); g_idle_add (quit_main_loop, loop); } else { g_object_set_data (G_OBJECT (pipeline), SERVER_RECEIVES, GINT_TO_POINTER (TRUE)); } G_UNLOCK (check_receive_lock); g_object_unref (pipeline); }
gboolean gst_element_sync_state_with_parent_target_state (GstElement * element) { GstElement *parent; GstState target; GstStateChangeReturn ret; g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); parent = GST_ELEMENT_CAST (gst_element_get_parent (element)); if (parent == NULL) { GST_DEBUG_OBJECT (element, "element has no parent"); return FALSE; } GST_OBJECT_LOCK (parent); target = GST_STATE_TARGET (parent); GST_OBJECT_UNLOCK (parent); GST_DEBUG_OBJECT (element, "setting parent (%s) target state %s", GST_ELEMENT_NAME (parent), gst_element_state_get_name (target)); gst_object_unref (parent); ret = gst_element_set_state (element, target); if (ret == GST_STATE_CHANGE_FAILURE) { GST_DEBUG_OBJECT (element, "setting target state failed (%s)", gst_element_state_change_return_get_name (ret)); return FALSE; } return TRUE; }
static void sendrecv_answerer_fakesink_hand_off (GstElement * fakesink, GstBuffer * buf, GstPad * pad, gpointer data) { HandOffData *hod = (HandOffData *) data; GstElement *pipeline; check_caps (pad, hod); pipeline = GST_ELEMENT (gst_element_get_parent (fakesink)); G_LOCK (check_receive_lock); if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (pipeline), OFFERER_RECEIVES_VIDEO))) { g_object_set (G_OBJECT (fakesink), "signal-handoffs", FALSE, NULL); g_idle_add (quit_main_loop_idle, hod->loop); } else { g_object_set_data (G_OBJECT (pipeline), ANSWERER_RECEIVES_VIDEO, GINT_TO_POINTER (TRUE)); } G_UNLOCK (check_receive_lock); g_object_unref (pipeline); }
static gboolean skype_audio_stream_post_create_stream (SkypeBaseStream *self, gpointer stream) { SkypeAudioStreamPrivate *priv = SKYPE_AUDIO_STREAM (self)->priv; FsuConference *fsuconf; FsConference *fsconf; FsuFilterManager *manager; FsuFilter *filter; FsuSink *sink; GstElement *parent; GstElement *src; /* Setup dynamic properties */ g_object_get (G_OBJECT (stream), "fsu-conference", &fsuconf, NULL); if (fsuconf == NULL) { g_warning ("Error fetching FsuConference"); return FALSE; } g_object_get (G_OBJECT (fsuconf), "fs-conference", &fsconf, NULL); g_object_unref (fsuconf); if (fsconf == NULL) { g_warning ("Error fetching FsConference"); return FALSE; } fs_element_added_notifier_add (priv->notifier, GST_BIN (fsconf)); g_object_unref (fsconf); /* Setup volume filter */ g_object_get (G_OBJECT (stream), "filter-manager", &manager, NULL); if (manager == NULL) { g_warning ("Error fetching FsuFilterManager"); return FALSE; } filter = FSU_FILTER (fsu_volume_filter_new ()); g_object_set (filter, "volume", priv->volume, NULL); priv->volume_id = fsu_filter_manager_prepend_filter (manager, filter); g_object_unref (manager); g_object_unref (filter); if (priv->volume_id == NULL) { g_warning ("Error adding resolution filter to filter manager."); return FALSE; } /* Setup DTMF source */ g_object_get (stream, "sink", &sink, NULL); if (sink == NULL) { g_warning ("Error fetching sink"); return FALSE; } src = gst_element_factory_make ("dtmfsrc", NULL); if (src == NULL) { g_warning ("Error creating dtmfsrc"); gst_object_unref (sink); return FALSE; } parent = GST_ELEMENT (gst_element_get_parent (sink)); if (parent == NULL) { g_warning ("Error fetching FsuSink parent"); gst_object_unref (src); gst_object_unref (sink); return FALSE; } if (!gst_bin_add (GST_BIN (parent), gst_object_ref (src))) { g_warning ("Error adding dtmfsrc to FsuSink parent"); /* Unref src twice if it fails as it's reffed in the call */ gst_object_unref (src); gst_object_unref (src); gst_object_unref (sink); gst_object_unref (parent); return FALSE; } gst_object_unref (parent); if (!gst_element_link (src, GST_ELEMENT (sink))) { g_warning ("Error adding dtmfsrc to FsuSink parent"); gst_object_unref (src); gst_object_unref (sink); return FALSE; } gst_object_unref (sink); if (!gst_element_sync_state_with_parent (src)) { g_warning ("Error syncing dtmfsrc state with parent"); gst_object_unref (src); return FALSE; } priv->dtmfsrc = src; priv->stream = g_object_ref (stream); return TRUE; }
static GstStateChangeReturn gst_visual_gl_change_state (GstElement * element, GstStateChange transition) { GstVisualGL *visual = GST_VISUAL_GL (element); GstStateChangeReturn ret; switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: break; case GST_STATE_CHANGE_READY_TO_PAUSED: { GstElement *parent = GST_ELEMENT (gst_element_get_parent (visual)); GstStructure *structure = NULL; GstQuery *query = NULL; gboolean isPerformed = FALSE; gchar *name; if (!parent) { GST_ELEMENT_ERROR (visual, CORE, STATE_CHANGE, (NULL), ("A parent bin is required")); return FALSE; } name = gst_element_get_name (visual); structure = gst_structure_new (name, NULL); query = gst_query_new_application (GST_QUERY_CUSTOM, structure); g_free (name); isPerformed = gst_element_query (parent, query); if (isPerformed) { const GValue *id_value = gst_structure_get_value (structure, "gstgldisplay"); if (G_VALUE_HOLDS_POINTER (id_value)) /* at least one gl element is after in our gl chain */ visual->display = gst_object_ref (GST_GL_DISPLAY (g_value_get_pointer (id_value))); else { /* this gl filter is a sink in terms of the gl chain */ visual->display = gst_gl_display_new (); gst_gl_display_create_context (visual->display, 0); //TODO visual->external_gl_context); } gst_visual_gl_reset (visual); visual->actor = visual_actor_new (GST_VISUAL_GL_GET_CLASS (visual)->plugin->info-> plugname); visual->video = visual_video_new (); visual->audio = visual_audio_new (); if (!visual->actor || !visual->video) goto actor_setup_failed; gst_gl_display_thread_add (visual->display, (GstGLDisplayThreadFunc) actor_setup, visual); if (visual->actor_setup_result != 0) goto actor_setup_failed; else visual_actor_set_video (visual->actor, visual->video); } gst_query_unref (query); gst_object_unref (GST_OBJECT (parent)); if (!isPerformed) return GST_STATE_CHANGE_FAILURE; } break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: break; default: break; } ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: break; case GST_STATE_CHANGE_PAUSED_TO_READY: { if (visual->fbo) { gst_gl_display_del_fbo (visual->display, visual->fbo, visual->depthbuffer); visual->fbo = 0; visual->depthbuffer = 0; } if (visual->midtexture) { gst_gl_display_del_texture (visual->display, visual->midtexture, visual->width, visual->height); visual->midtexture = 0; } if (visual->display) { gst_object_unref (visual->display); visual->display = NULL; } gst_visual_gl_clear_actors (visual); } break; case GST_STATE_CHANGE_READY_TO_NULL: break; default: break; } return ret; /* ERRORS */ actor_setup_failed: { GST_ELEMENT_ERROR (visual, LIBRARY, INIT, (NULL), ("could not set up actor")); gst_visual_gl_clear_actors (visual); return GST_STATE_CHANGE_FAILURE; } }
static void remove_agnostic_bin (GstElement * agnosticbin) { KmsAudioMixer *self; GstElement *audiorate = NULL, *typefind = NULL; GstPad *sinkpad, *peerpad; self = (KmsAudioMixer *) gst_element_get_parent (agnosticbin); if (self == NULL) { GST_WARNING_OBJECT (agnosticbin, "No parent element"); return; } sinkpad = gst_element_get_static_pad (agnosticbin, "sink"); peerpad = gst_pad_get_peer (sinkpad); if (peerpad == NULL) { GST_WARNING_OBJECT (sinkpad, "Not linked"); gst_object_unref (sinkpad); goto end; } audiorate = gst_pad_get_parent_element (peerpad); gst_object_unref (sinkpad); gst_object_unref (peerpad); if (audiorate == NULL) { GST_WARNING_OBJECT (self, "No audiorate"); goto end; } sinkpad = gst_element_get_static_pad (audiorate, "sink"); peerpad = gst_pad_get_peer (sinkpad); if (peerpad == NULL) { GST_WARNING_OBJECT (sinkpad, "Not linked"); gst_object_unref (sinkpad); goto end; } typefind = gst_pad_get_parent_element (peerpad); gst_object_unref (sinkpad); gst_object_unref (peerpad); if (typefind == NULL) { GST_WARNING_OBJECT (self, "No typefind"); goto end; } gst_element_unlink_many (typefind, audiorate, agnosticbin, NULL); gst_element_set_locked_state (typefind, TRUE); gst_element_set_locked_state (audiorate, TRUE); gst_element_set_locked_state (agnosticbin, TRUE); gst_element_set_state (typefind, GST_STATE_NULL); gst_element_set_state (audiorate, GST_STATE_NULL); gst_element_set_state (agnosticbin, GST_STATE_NULL); gst_object_ref (agnosticbin); gst_bin_remove_many (GST_BIN (self), typefind, audiorate, agnosticbin, NULL); gst_object_unref (agnosticbin); end: if (audiorate != NULL) { gst_object_unref (audiorate); } if (typefind != NULL) { gst_object_unref (typefind); } gst_object_unref (self); }
/* callback called when demux creates a src pad. * We will create an AppSink to get the data */ static void on_demuxNewPad (GstElement * demux, GstPad * pad, gpointer user_data) { GstAdaptiveDemuxTestEnginePrivate *priv = (GstAdaptiveDemuxTestEnginePrivate *) user_data; GstElement *pipeline; GstElement *sink; gboolean ret; gchar *name; GstPad *appsink_pad; GstAppSinkCallbacks appSinkCallbacks; GstAdaptiveDemuxTestOutputStream *stream; GObjectClass *gobject_class; fail_unless (priv != NULL); name = gst_pad_get_name (pad); stream = g_slice_new0 (GstAdaptiveDemuxTestOutputStream); GST_DEBUG ("created pad %p", pad); sink = gst_element_factory_make ("appsink", name); g_free (name); fail_unless (sink != NULL); GST_TEST_LOCK (priv); /* register the AppSink pointer in the test output data */ gst_object_ref (sink); stream->appsink = GST_APP_SINK (sink); appSinkCallbacks.eos = on_appSinkEOS; appSinkCallbacks.new_preroll = NULL; appSinkCallbacks.new_sample = on_appSinkNewSample; gst_app_sink_set_callbacks (GST_APP_SINK (sink), &appSinkCallbacks, priv, NULL); appsink_pad = gst_element_get_static_pad (sink, "sink"); gst_pad_add_probe (appsink_pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GST_PAD_PROBE_TYPE_EVENT_FLUSH, (GstPadProbeCallback) on_appsink_event, priv, NULL); gst_object_unref (appsink_pad); gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, (GstPadProbeCallback) on_demux_sent_data, priv, NULL); gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GST_PAD_PROBE_TYPE_EVENT_FLUSH, (GstPadProbeCallback) on_demux_sent_event, priv, NULL); gobject_class = G_OBJECT_GET_CLASS (sink); if (g_object_class_find_property (gobject_class, "sync")) { GST_DEBUG ("Setting sync=FALSE on AppSink"); g_object_set (G_OBJECT (sink), "sync", FALSE, NULL); } stream->pad = gst_object_ref (pad); g_ptr_array_add (priv->engine.output_streams, stream); GST_TEST_UNLOCK (priv); pipeline = GST_ELEMENT (gst_element_get_parent (demux)); fail_unless (pipeline != NULL); ret = gst_bin_add (GST_BIN (pipeline), sink); fail_unless_equals_int (ret, TRUE); gst_object_unref (pipeline); ret = gst_element_link (demux, sink); fail_unless_equals_int (ret, TRUE); ret = gst_element_sync_state_with_parent (sink); fail_unless_equals_int (ret, TRUE); GST_TEST_LOCK (priv); if (priv->callbacks->demux_pad_added) { priv->callbacks->demux_pad_added (&priv->engine, stream, priv->user_data); } GST_TEST_UNLOCK (priv); }
OwrMediaSource *_owr_uri_source_new(OwrMediaType media_type, guint stream_id, OwrCodecType codec_type, gpointer uridecodebin_ptr) { GstElement *uridecodebin = GST_ELEMENT(uridecodebin_ptr); OwrURISource *source; OwrURISourcePrivate *priv; GEnumClass *enum_class; GEnumValue *enum_value; gchar *name; GstElement *uri_pipeline; GstElement *identity; GstElement *source_bin, *tee; GstElement *fakesink, *queue; GstPad *srcpad, *sinkpad, *ghostpad; gchar *pad_name, *bin_name; enum_class = G_ENUM_CLASS(g_type_class_ref(OWR_TYPE_MEDIA_TYPE)); enum_value = g_enum_get_value(enum_class, media_type); name = g_strdup_printf("%s stream, id: %u", enum_value ? enum_value->value_nick : "unknown", stream_id); g_type_class_unref(enum_class); source = g_object_new(OWR_TYPE_URI_SOURCE, "name", name, "media-type", media_type, NULL); priv = source->priv; priv->stream_id = stream_id; g_free(name); _owr_media_source_set_codec(OWR_MEDIA_SOURCE(source), codec_type); /* create source tee and everything */ if (media_type == OWR_MEDIA_TYPE_VIDEO) bin_name = g_strdup_printf("video-src-%u-%u", codec_type, stream_id); else if (media_type == OWR_MEDIA_TYPE_AUDIO) bin_name = g_strdup_printf("audio-src-%u-%u", codec_type, stream_id); else g_assert_not_reached(); pad_name = g_strdup_printf("src_%u", stream_id); source_bin = gst_bin_new(bin_name); _owr_media_source_set_source_bin(OWR_MEDIA_SOURCE(source), source_bin); identity = gst_element_factory_make("identity", "identity"); g_object_set(identity, "sync", TRUE, NULL); tee = gst_element_factory_make("tee", "tee"); _owr_media_source_set_source_tee(OWR_MEDIA_SOURCE(source), tee); fakesink = gst_element_factory_make("fakesink", "fakesink"); g_object_set(fakesink, "async", FALSE, NULL); g_object_set(fakesink, "enable-last-sample", FALSE, NULL); queue = gst_element_factory_make("queue", "queue"); g_free(bin_name); uri_pipeline = GST_ELEMENT(gst_element_get_parent(uridecodebin)); gst_bin_add_many(GST_BIN(source_bin), identity, tee, queue, fakesink, NULL); LINK_ELEMENTS(identity, tee); LINK_ELEMENTS(tee, queue); LINK_ELEMENTS(queue, fakesink); sinkpad = gst_element_get_static_pad(identity, "sink"); ghostpad = gst_ghost_pad_new("sink", sinkpad); gst_object_unref(sinkpad); gst_element_add_pad(source_bin, ghostpad); gst_bin_add(GST_BIN(uri_pipeline), source_bin); gst_element_sync_state_with_parent(source_bin); gst_object_unref(uri_pipeline); /* Link the uridecodebin to our tee */ srcpad = gst_element_get_static_pad(uridecodebin, pad_name); g_free(pad_name); if (gst_pad_link(srcpad, ghostpad) != GST_PAD_LINK_OK) GST_ERROR("Failed to link source bin to the outside"); return OWR_MEDIA_SOURCE(source); }
static void test_with_caps (GstElement * src, GstElement * videocrop, GstCaps * caps) { GstClockTime time_run; GstElement *pipeline; GTimer *timer; GstBus *bus; GstPad *pad; guint hcrop; guint vcrop; /* caps must be writable, we can't check that here though */ g_assert (GST_CAPS_REFCOUNT_VALUE (caps) == 1); timer = g_timer_new (); vcrop = 0; hcrop = 0; pipeline = GST_ELEMENT (gst_element_get_parent (videocrop)); g_assert (GST_IS_PIPELINE (pipeline)); /* at this point the pipeline is in PLAYING state; we only want to capture * errors resulting from our on-the-fly changing of the filtercaps */ bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); /* pad to block */ pad = gst_element_get_static_pad (src, "src"); time_run = 0; do { GstClockTime wait_time, waited_for_block; if (check_bus_for_errors (bus, 0)) break; wait_time = GST_SECOND / FRAMERATE; GST_LOG ("hcrop = %3d, vcrop = %3d", vcrop, hcrop); g_timer_reset (timer); /* need to block the streaming thread while changing these properties, * otherwise we might get random not-negotiated errors (when caps are * changed in between upstream calling pad_alloc_buffer() and pushing * the processed buffer?) */ gst_pad_set_blocked (pad, TRUE); g_object_set (videocrop, "left", hcrop, "top", vcrop, NULL); gst_pad_set_blocked (pad, FALSE); waited_for_block = g_timer_elapsed (timer, NULL) * (double) GST_SECOND; /* GST_LOG ("waited: %" GST_TIME_FORMAT ", frame len: %" GST_TIME_FORMAT, GST_TIME_ARGS (waited_for_block), GST_TIME_ARGS (wait_time)); */ ++vcrop; ++hcrop; if (wait_time > waited_for_block) { g_usleep ((wait_time - waited_for_block) / GST_MSECOND); } time_run += wait_time; } while (time_run < (TIME_PER_TEST * GST_SECOND)); g_timer_destroy (timer); gst_object_unref (bus); gst_object_unref (pad); }