static void kms_agnostic_bin2_link_to_tee (KmsAgnosticBin2 * self, GstPad * pad, GstElement * tee, GstCaps * caps) { GstElement *queue = gst_element_factory_make ("queue", NULL); GstPad *target; gst_bin_add (GST_BIN (self), queue); gst_element_sync_state_with_parent (queue); if (!gst_caps_is_any (caps) && is_raw_caps (caps)) { GstElement *convert = kms_utils_create_convert_for_caps (caps); GstElement *rate = kms_utils_create_rate_for_caps (caps); GstElement *mediator = kms_utils_create_mediator_element (caps); remove_element_on_unlinked (convert, "src", "sink"); remove_element_on_unlinked (rate, "src", "sink"); remove_element_on_unlinked (mediator, "src", "sink"); gst_bin_add_many (GST_BIN (self), convert, rate, mediator, NULL); gst_element_sync_state_with_parent (mediator); gst_element_sync_state_with_parent (convert); gst_element_sync_state_with_parent (rate); gst_element_link_many (queue, rate, convert, mediator, NULL); target = gst_element_get_static_pad (mediator, "src"); } else { target = gst_element_get_static_pad (queue, "src"); } gst_ghost_pad_set_target (GST_GHOST_PAD (pad), target); g_object_unref (target); link_element_to_tee (tee, queue); }
static void kms_agnostic_bin2_link_to_tee (KmsAgnosticBin2 * self, GstPad * pad, GstElement * tee, GstCaps * caps) { GstElement *queue = gst_element_factory_make ("queue", NULL); GstPad *target; GstProxyPad *proxy; gst_bin_add (GST_BIN (self), queue); gst_element_sync_state_with_parent (queue); if (!(gst_caps_is_any (caps) || gst_caps_is_empty (caps)) && kms_utils_caps_are_raw (caps)) { GstElement *convert = kms_utils_create_convert_for_caps (caps); GstElement *rate = kms_utils_create_rate_for_caps (caps); GstElement *mediator = kms_utils_create_mediator_element (caps); remove_element_on_unlinked (convert, "src", "sink"); if (rate) { remove_element_on_unlinked (rate, "src", "sink"); } remove_element_on_unlinked (mediator, "src", "sink"); if (rate) { gst_bin_add (GST_BIN (self), rate); } gst_bin_add_many (GST_BIN (self), convert, mediator, NULL); gst_element_sync_state_with_parent (mediator); gst_element_sync_state_with_parent (convert); if (rate) { gst_element_sync_state_with_parent (rate); } if (rate) { gst_element_link_many (queue, rate, mediator, NULL); } else { gst_element_link (queue, mediator); } gst_element_link_many (mediator, convert, NULL); target = gst_element_get_static_pad (convert, "src"); } else { target = gst_element_get_static_pad (queue, "src"); } gst_ghost_pad_set_target (GST_GHOST_PAD (pad), target); proxy = gst_proxy_pad_get_internal (GST_PROXY_PAD (pad)); gst_pad_set_query_function (GST_PAD_CAST (proxy), proxy_src_pad_query_function); g_object_unref (proxy); g_object_unref (target); link_element_to_tee (tee, queue); }
static gboolean kms_enc_tree_bin_configure (KmsEncTreeBin * self, const GstCaps * caps, gint target_bitrate) { KmsTreeBin *tree_bin = KMS_TREE_BIN (self); GstElement *rate, *convert, *mediator, *output_tee, *capsfilter = NULL; self->priv->current_bitrate = target_bitrate; kms_enc_tree_bin_create_encoder_for_caps (self, caps, target_bitrate); if (self->priv->enc == NULL) { GST_WARNING_OBJECT (self, "Invalid encoder for caps: %" GST_PTR_FORMAT, caps); return FALSE; } GST_DEBUG_OBJECT (self, "Encoder found: %" GST_PTR_FORMAT, self->priv->enc); self->priv->enc_sink = gst_element_get_static_pad (self->priv->enc, "sink"); self->priv->remb_manager = kms_utils_remb_event_manager_create (self->priv->enc_sink); kms_utils_remb_event_manager_set_callback (self->priv->remb_manager, bitrate_callback, self, NULL); gst_pad_add_probe (self->priv->enc_sink, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, tag_event_probe, self, NULL); rate = kms_utils_create_rate_for_caps (caps); convert = kms_utils_create_convert_for_caps (caps); mediator = kms_utils_create_mediator_element (caps); gst_bin_add_many (GST_BIN (self), rate, convert, mediator, self->priv->enc, NULL); gst_element_sync_state_with_parent (self->priv->enc); gst_element_sync_state_with_parent (mediator); gst_element_sync_state_with_parent (convert); gst_element_sync_state_with_parent (rate); // FIXME: This is a hack to avoid an error on x264enc that does not work // properly with some raw formats, this should be fixed in gstreamer // but until this is done this hack makes it work if (self->priv->enc_type == X264) { GstCaps *filter_caps = gst_caps_from_string ("video/x-raw,format=I420"); GstPad *sink; capsfilter = gst_element_factory_make ("capsfilter", NULL); sink = gst_element_get_static_pad (capsfilter, "sink"); gst_pad_add_probe (sink, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, check_caps_probe, NULL, NULL); g_object_unref (sink); g_object_set (capsfilter, "caps", filter_caps, NULL); gst_caps_unref (filter_caps); gst_bin_add (GST_BIN (self), capsfilter); gst_element_sync_state_with_parent (capsfilter); } kms_tree_bin_set_input_element (tree_bin, rate); output_tee = kms_tree_bin_get_output_tee (tree_bin); if (self->priv->enc_type == X264) { gst_element_link_many (rate, convert, mediator, capsfilter, self->priv->enc, output_tee, NULL); } else { gst_element_link_many (rate, convert, mediator, self->priv->enc, output_tee, NULL); } return TRUE; }