void kms_agnostic_bin2_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) { KmsAgnosticBin2 *self = KMS_AGNOSTIC_BIN2 (object); switch (property_id) { case PROP_MIN_BITRATE: KMS_AGNOSTIC_BIN2_LOCK (self); g_value_set_int (value, self->priv->min_bitrate); KMS_AGNOSTIC_BIN2_UNLOCK (self); break; case PROP_MAX_BITRATE: KMS_AGNOSTIC_BIN2_LOCK (self); g_value_set_int (value, self->priv->max_bitrate); KMS_AGNOSTIC_BIN2_UNLOCK (self); break; case PROP_CODEC_CONFIG: KMS_AGNOSTIC_BIN2_LOCK (self); g_value_set_boxed (value, self->priv->codec_config); KMS_AGNOSTIC_BIN2_UNLOCK (self); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } }
void kms_agnostic_bin2_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) { KmsAgnosticBin2 *self = KMS_AGNOSTIC_BIN2 (object); switch (property_id) { case PROP_MIN_BITRATE:{ gint v; v = g_value_get_int (value); KMS_AGNOSTIC_BIN2_LOCK (self); if (v > self->priv->max_bitrate) { v = self->priv->max_bitrate; GST_WARNING_OBJECT (self, "Setting min-bitrate bigger than max-bitrate"); } self->priv->min_bitrate = v; GST_DEBUG_OBJECT (self, "min_bitrate configured %d", self->priv->min_bitrate); kms_agnostic_bin_set_encoders_bitrate (self); KMS_AGNOSTIC_BIN2_UNLOCK (self); break; } case PROP_MAX_BITRATE:{ gint v; v = g_value_get_int (value); KMS_AGNOSTIC_BIN2_LOCK (self); if (v < self->priv->min_bitrate) { v = self->priv->min_bitrate; GST_WARNING_OBJECT (self, "Setting max-bitrate less than min-bitrate"); } self->priv->max_bitrate = v; GST_DEBUG ("max_bitrate configured %d", self->priv->max_bitrate); kms_agnostic_bin_set_encoders_bitrate (self); KMS_AGNOSTIC_BIN2_UNLOCK (self); break; } case PROP_CODEC_CONFIG: KMS_AGNOSTIC_BIN2_LOCK (self); if (self->priv->codec_config) { gst_structure_free (self->priv->codec_config); self->priv->codec_config = NULL; } self->priv->codec_config = g_value_dup_boxed (value); KMS_AGNOSTIC_BIN2_UNLOCK (self); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } }
static void kms_agnostic_bin2_dispose (GObject * object) { KmsAgnosticBin2 *self = KMS_AGNOSTIC_BIN2 (object); GST_DEBUG_OBJECT (object, "dispose"); KMS_AGNOSTIC_BIN2_LOCK (self); g_thread_pool_free (self->priv->remove_pool, FALSE, FALSE); if (self->priv->input_bin_src_caps) { gst_caps_unref (self->priv->input_bin_src_caps); self->priv->input_bin_src_caps = NULL; } if (self->priv->input_caps) { gst_caps_unref (self->priv->input_caps); self->priv->input_caps = NULL; } KMS_AGNOSTIC_BIN2_UNLOCK (self); /* chain up */ G_OBJECT_CLASS (kms_agnostic_bin2_parent_class)->dispose (object); }
static GstPadProbeReturn kms_agnostic_bin2_src_reconfigure_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data) { KmsAgnosticBin2 *self = KMS_AGNOSTIC_BIN2 (gst_pad_get_parent_element (pad)); GstPadProbeReturn ret = GST_PAD_PROBE_OK; GstEvent *event; if (self == NULL) { return GST_PAD_PROBE_OK; } if (GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_EVENT_BOTH) { event = gst_pad_probe_info_get_event (info); if (GST_EVENT_TYPE (event) == GST_EVENT_RECONFIGURE) { KmsAgnosticBin2 *self = user_data; GST_DEBUG_OBJECT (pad, "Received reconfigure event"); KMS_AGNOSTIC_BIN2_LOCK (self); kms_agnostic_bin2_process_pad (self, pad); ret = GST_PAD_PROBE_DROP; KMS_AGNOSTIC_BIN2_UNLOCK (self); goto end; } } end: g_object_unref (self); return ret; }
static GstPadProbeReturn kms_agnostic_bin2_sink_caps_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data) { KmsAgnosticBin2 *self; GstCaps *current_caps; GstCaps *new_caps = NULL; GstEvent *event = gst_pad_probe_info_get_event (info); if (GST_EVENT_TYPE (event) != GST_EVENT_CAPS) { return GST_PAD_PROBE_OK; } GST_TRACE_OBJECT (pad, "Event: %" GST_PTR_FORMAT, event); self = KMS_AGNOSTIC_BIN2 (user_data); gst_event_parse_caps (event, &new_caps); if (new_caps == NULL) { GST_ERROR_OBJECT (self, "Unexpected NULL caps"); return GST_PAD_PROBE_OK; } KMS_AGNOSTIC_BIN2_LOCK (self); current_caps = self->priv->input_caps; self->priv->input_caps = gst_caps_copy (new_caps); KMS_AGNOSTIC_BIN2_UNLOCK (self); GST_TRACE_OBJECT (user_data, "New caps event: %" GST_PTR_FORMAT, event); if (current_caps != NULL) { GstStructure *st; GST_TRACE_OBJECT (user_data, "Current caps: %" GST_PTR_FORMAT, current_caps); st = gst_caps_get_structure (current_caps, 0); // Remove famerate, width, height, streamheader that make unecessary // agnostic reconstruction happen gst_structure_remove_fields (st, "width", "height", "framerate", "streamheader", "codec_data", NULL); if (!gst_caps_can_intersect (new_caps, current_caps) && !is_raw_caps (current_caps) && !is_raw_caps (new_caps)) { GST_DEBUG_OBJECT (user_data, "Caps differ caps: %" GST_PTR_FORMAT, new_caps); kms_agnostic_bin2_configure_input (self, new_caps); } gst_caps_unref (current_caps); } else { GST_DEBUG_OBJECT (user_data, "No previous caps, starting"); kms_agnostic_bin2_configure_input (self, new_caps); } return GST_PAD_PROBE_OK; }
static void kms_agnostic_bin2_src_unlinked (GstPad * pad, GstPad * peer, KmsAgnosticBin2 * self) { GST_DEBUG_OBJECT (pad, "Unlinked"); KMS_AGNOSTIC_BIN2_LOCK (self); GST_OBJECT_FLAG_UNSET (pad, KMS_AGNOSTIC_PAD_STARTED); remove_target_pad (pad); KMS_AGNOSTIC_BIN2_UNLOCK (self); }
void kms_agnostic_bin2_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) { KmsAgnosticBin2 *self = KMS_AGNOSTIC_BIN2 (object); switch (property_id) { case PROP_DEFAULT_BITRATE: KMS_AGNOSTIC_BIN2_LOCK (self); g_value_set_int (value, self->priv->default_bitrate); KMS_AGNOSTIC_BIN2_UNLOCK (self); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } }
static GstPadProbeReturn input_bin_src_caps_probe (GstPad * pad, GstPadProbeInfo * info, gpointer bin) { KmsAgnosticBin2 *self = KMS_AGNOSTIC_BIN2 (GST_OBJECT_PARENT (bin)); GstEvent *event = gst_pad_probe_info_get_event (info); GstCaps *current_caps; if (self == NULL) { GST_WARNING_OBJECT (bin, "Parent agnosticbin seems to be released"); return GST_PAD_PROBE_OK; } GST_TRACE_OBJECT (self, "Event in parser pad: %" GST_PTR_FORMAT, event); if (GST_EVENT_TYPE (event) != GST_EVENT_CAPS) { return GST_PAD_PROBE_OK; } KMS_AGNOSTIC_BIN2_LOCK (self); self->priv->started = TRUE; if (self->priv->input_bin_src_caps != NULL) { gst_caps_unref (self->priv->input_bin_src_caps); } gst_event_parse_caps (event, ¤t_caps); self->priv->input_bin_src_caps = gst_caps_copy (current_caps); kms_agnostic_bin2_insert_bin (self, GST_BIN (bin)); GST_INFO_OBJECT (self, "Setting current caps to: %" GST_PTR_FORMAT, current_caps); kms_element_for_each_src_pad (GST_ELEMENT (self), (KmsPadIterationAction) add_linked_pads, self); KMS_AGNOSTIC_BIN2_UNLOCK (self); return GST_PAD_PROBE_REMOVE; }
static void kms_agnostic_bin2_configure_input (KmsAgnosticBin2 * self, const GstCaps * caps) { KmsParseTreeBin *parse_bin; GstElement *parser; GstPad *parser_src; GstElement *input_element; KMS_AGNOSTIC_BIN2_LOCK (self); if (self->priv->input_bin != NULL) { kms_tree_bin_unlink_input_element_from_tee (KMS_TREE_BIN (self-> priv->input_bin)); } parse_bin = kms_parse_tree_bin_new (caps); self->priv->input_bin = GST_BIN (parse_bin); parser = kms_parse_tree_bin_get_parser (KMS_PARSE_TREE_BIN (parse_bin)); parser_src = gst_element_get_static_pad (parser, "src"); gst_pad_add_probe (parser_src, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, input_bin_src_caps_probe, g_object_ref (parse_bin), g_object_unref); g_object_unref (parser_src); gst_bin_add (GST_BIN (self), GST_ELEMENT (parse_bin)); gst_element_sync_state_with_parent (GST_ELEMENT (parse_bin)); input_element = kms_tree_bin_get_input_element (KMS_TREE_BIN (parse_bin)); link_element_to_tee (self->priv->input_tee, input_element); self->priv->started = FALSE; GST_DEBUG ("Removing old treebins"); g_hash_table_foreach (self->priv->bins, remove_bin, self); g_hash_table_remove_all (self->priv->bins); KMS_AGNOSTIC_BIN2_UNLOCK (self); }
static gboolean proxy_src_pad_query_function (GstPad * pad, GstObject * parent, GstQuery * query) { gboolean ret = gst_pad_query_default (pad, parent, query); if (!ret) { return ret; } if (GST_QUERY_TYPE (query) == GST_QUERY_ACCEPT_CAPS) { gboolean accepted; gst_query_parse_accept_caps_result (query, &accepted); if (!accepted) { GstProxyPad *gp = gst_proxy_pad_get_internal (GST_PROXY_PAD (pad)); KmsAgnosticBin2 *self = NULL; GST_ERROR_OBJECT (pad, "Caps not accepted: %" GST_PTR_FORMAT, query); if (gp) { self = KMS_AGNOSTIC_BIN2 (GST_OBJECT_PARENT (gp)); } if (self) { KMS_AGNOSTIC_BIN2_LOCK (self); remove_target_pad (GST_PAD_CAST (gp)); kms_agnostic_bin2_process_pad (self, GST_PAD_CAST (gp)); KMS_AGNOSTIC_BIN2_UNLOCK (self); } g_object_unref (gp); } } return ret; }