<commit_before>#include <kms-core.h>
#include <rtp/kms-rtp.h>
#include "internal/kms-utils.h"

#define KMS_RTP_RECEIVER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), KMS_TYPE_RTP_RECEIVER, KmsRtpReceiverPriv))

#define LOCK(obj) (g_mutex_lock(KMS_RTP_RECEIVER(obj)->priv->mutex))
#define UNLOCK(obj) (g_mutex_unlock(KMS_RTP_RECEIVER(obj)->priv->mutex))

struct _KmsRtpReceiverPriv {
	GMutex *mutex;

	KmsSdpMedia *local_spec;

	GstElement *udpsrc;

	gint audio_port;
	gint video_port;
};

enum {
	PROP_0,

	PROP_LOCAL_SPEC,
};

G_DEFINE_TYPE(KmsRtpReceiver, kms_rtp_receiver, KMS_TYPE_MEDIA_HANDLER_SRC)

static void
dispose_local_spec(KmsRtpReceiver *self) {
	if (self->priv->local_spec != NULL) {
		g_object_unref(self->priv->local_spec);
		self->priv->local_spec = NULL;
	}
}

void
kms_rtp_receiver_terminate(KmsRtpReceiver *self) {
	LOCK(self);
	if (self->priv->udpsrc) {
		gst_element_send_event(self->priv->udpsrc,
						gst_event_new_flush_start());
		self->priv->udpsrc = NULL;
	}
	UNLOCK(self);
}

static void
set_property (GObject *object, guint property_id, const GValue *value,
							GParamSpec *pspec) {
	KmsRtpReceiver *self = KMS_RTP_RECEIVER(object);

	switch (property_id) {
		case PROP_LOCAL_SPEC:
			LOCK(self);
			dispose_local_spec(self);
			self->priv->local_spec = g_value_dup_object(value);
			UNLOCK(self);
			break;
		default:
			/* We don't have any other property... */
			G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
			break;
	}
}

static void
get_property(GObject *object, guint property_id, GValue *value,
							GParamSpec *pspec) {
	KmsRtpReceiver *self = KMS_RTP_RECEIVER(object);

	switch (property_id) {
		case PROP_LOCAL_SPEC:
			LOCK(self);
			g_value_set_object(value, self->priv->local_spec);
			UNLOCK(self);
			break;
		default:
			/* We don't have any other property... */
			G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
			break;
	}
}

static GSList*
get_pay_list(KmsSdpMedia *media){
	GSList *list = NULL;
	GValueArray *payloads;
	gint i;

	g_object_get(media, "payloads", &payloads, NULL);

	for (i = 0; i < payloads->n_values; i++) {
		KmsSdpPayload *aux;

		aux = g_value_get_object(g_value_array_get_nth(payloads, i));
		list = g_slist_prepend(list, aux);
	}
	g_value_array_free(payloads);

	return list;
}

static gint
compare_pay_pt(gconstpointer ppay, gconstpointer ppt) {
	KmsSdpPayload *pay = (gpointer) ppay;
	guint pt;

	g_object_get(pay, "payload", &pt, NULL);

	return pt - (*(int *)ppt);
}

static GstCaps*
get_caps_for_pt(KmsRtpReceiver *self, guint pt) {
	GValueArray *medias;
	GSList *payloads = NULL;
	GstCaps *caps = NULL;
	GSList *l;
	gint i;

	LOCK(self);
	g_object_get(self->priv->local_spec, "medias", &medias, NULL);
	for (i = 0; i < medias->n_values; i++) {
		KmsSdpMedia *aux;
		KmsMediaType type;

		aux = g_value_get_object(g_value_array_get_nth(medias, i));
		g_object_get(aux, "type", &type, NULL);
		switch (type) {
		case KMS_MEDIA_TYPE_AUDIO:
			payloads = g_slist_concat(payloads, get_pay_list(aux));
			break;
		case KMS_MEDIA_TYPE_VIDEO:
			payloads = g_slist_concat(payloads, get_pay_list(aux));
			break;
		default:
			/* No action */
			break;
		}
	}

	l = g_slist_find_custom(payloads, &pt, compare_pay_pt);

	if (l != NULL)
		caps = kms_sdp_payload_to_caps(l->data);

	UNLOCK(self);

	g_value_array_free(medias);
	g_slist_free(payloads);
	return caps;
}

static GstCaps*
request_pt_map(GstElement *demux, guint pt, gpointer self) {
	GstCaps *caps;

	caps = get_caps_for_pt(self, pt);

	if (caps != NULL && gst_caps_is_fixed(caps)) {
		return caps;
	}

	if (caps != NULL)
		gst_caps_unref(caps);

	return NULL;
}

static void
connect_depay_chain(KmsRtpReceiver *self, GstElement *orig, GstCaps *caps) {
	GstElement *depay;

	depay = kms_utils_get_element_for_caps(
					GST_ELEMENT_FACTORY_TYPE_DEPAYLOADER,
					GST_RANK_NONE, caps, GST_PAD_SINK,
					FALSE, NULL);
	g_return_if_fail(depay != NULL);
	gst_element_set_state(depay, GST_STATE_PLAYING);
	gst_bin_add(GST_BIN(self), depay);
	kms_dynamic_connection(orig, depay, "src");

	/* TODO: Connect typedef and notify parent of the available pads */
}

static void
new_payload_type(GstElement *demux, guint pt, GstPad *pad, gpointer user_data) {
	GstCaps *caps;
	gint len, i;
	gboolean has_clockrate = FALSE;<commit_msg>Connect a typefind to depayloader element<commit_after>#include <kms-core.h>
#include <rtp/kms-rtp.h>
#include "internal/kms-utils.h"

#define KMS_RTP_RECEIVER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), KMS_TYPE_RTP_RECEIVER, KmsRtpReceiverPriv))

#define LOCK(obj) (g_mutex_lock(KMS_RTP_RECEIVER(obj)->priv->mutex))
#define UNLOCK(obj) (g_mutex_unlock(KMS_RTP_RECEIVER(obj)->priv->mutex))

struct _KmsRtpReceiverPriv {
	GMutex *mutex;

	KmsSdpMedia *local_spec;

	GstElement *udpsrc;

	gint audio_port;
	gint video_port;
};

enum {
	PROP_0,

	PROP_LOCAL_SPEC,
};

G_DEFINE_TYPE(KmsRtpReceiver, kms_rtp_receiver, KMS_TYPE_MEDIA_HANDLER_SRC)

static void
dispose_local_spec(KmsRtpReceiver *self) {
	if (self->priv->local_spec != NULL) {
		g_object_unref(self->priv->local_spec);
		self->priv->local_spec = NULL;
	}
}

void
kms_rtp_receiver_terminate(KmsRtpReceiver *self) {
	LOCK(self);
	if (self->priv->udpsrc) {
		gst_element_send_event(self->priv->udpsrc,
						gst_event_new_flush_start());
		self->priv->udpsrc = NULL;
	}
	UNLOCK(self);
}

static void
set_property (GObject *object, guint property_id, const GValue *value,
							GParamSpec *pspec) {
	KmsRtpReceiver *self = KMS_RTP_RECEIVER(object);

	switch (property_id) {
		case PROP_LOCAL_SPEC:
			LOCK(self);
			dispose_local_spec(self);
			self->priv->local_spec = g_value_dup_object(value);
			UNLOCK(self);
			break;
		default:
			/* We don't have any other property... */
			G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
			break;
	}
}

static void
get_property(GObject *object, guint property_id, GValue *value,
							GParamSpec *pspec) {
	KmsRtpReceiver *self = KMS_RTP_RECEIVER(object);

	switch (property_id) {
		case PROP_LOCAL_SPEC:
			LOCK(self);
			g_value_set_object(value, self->priv->local_spec);
			UNLOCK(self);
			break;
		default:
			/* We don't have any other property... */
			G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
			break;
	}
}

static GSList*
get_pay_list(KmsSdpMedia *media){
	GSList *list = NULL;
	GValueArray *payloads;
	gint i;

	g_object_get(media, "payloads", &payloads, NULL);

	for (i = 0; i < payloads->n_values; i++) {
		KmsSdpPayload *aux;

		aux = g_value_get_object(g_value_array_get_nth(payloads, i));
		list = g_slist_prepend(list, aux);
	}
	g_value_array_free(payloads);

	return list;
}

static gint
compare_pay_pt(gconstpointer ppay, gconstpointer ppt) {
	KmsSdpPayload *pay = (gpointer) ppay;
	guint pt;

	g_object_get(pay, "payload", &pt, NULL);

	return pt - (*(int *)ppt);
}

static GstCaps*
get_caps_for_pt(KmsRtpReceiver *self, guint pt) {
	GValueArray *medias;
	GSList *payloads = NULL;
	GstCaps *caps = NULL;
	GSList *l;
	gint i;

	LOCK(self);
	g_object_get(self->priv->local_spec, "medias", &medias, NULL);
	for (i = 0; i < medias->n_values; i++) {
		KmsSdpMedia *aux;
		KmsMediaType type;

		aux = g_value_get_object(g_value_array_get_nth(medias, i));
		g_object_get(aux, "type", &type, NULL);
		switch (type) {
		case KMS_MEDIA_TYPE_AUDIO:
			payloads = g_slist_concat(payloads, get_pay_list(aux));
			break;
		case KMS_MEDIA_TYPE_VIDEO:
			payloads = g_slist_concat(payloads, get_pay_list(aux));
			break;
		default:
			/* No action */
			break;
		}
	}

	l = g_slist_find_custom(payloads, &pt, compare_pay_pt);

	if (l != NULL)
		caps = kms_sdp_payload_to_caps(l->data);

	UNLOCK(self);

	g_value_array_free(medias);
	g_slist_free(payloads);
	return caps;
}

static GstCaps*
request_pt_map(GstElement *demux, guint pt, gpointer self) {
	GstCaps *caps;

	caps = get_caps_for_pt(self, pt);

	if (caps != NULL && gst_caps_is_fixed(caps)) {
		return caps;
	}

	if (caps != NULL)
		gst_caps_unref(caps);

	return NULL;
}

static void
found_type(GstElement* tf, guint probability, GstCaps* caps, gpointer data) {

	g_print("Found type\n");
}

static void
connect_depay_chain(KmsRtpReceiver *self, GstElement *orig, GstCaps *caps) {
	GstElement *depay, *typefind;

	depay = kms_utils_get_element_for_caps(
					GST_ELEMENT_FACTORY_TYPE_DEPAYLOADER,
					GST_RANK_NONE, caps, GST_PAD_SINK,
					FALSE, NULL);
	g_return_if_fail(depay != NULL);
	gst_element_set_state(depay, GST_STATE_PLAYING);
	gst_bin_add(GST_BIN(self), depay);
	kms_dynamic_connection(orig, depay, "src");

	/* TODO: Connect typefind and notify parent of the available pads */
	typefind = gst_element_factory_make("typefind", NULL);
	gst_element_set_state(typefind, GST_STATE_PLAYING);
	gst_bin_add(GST_BIN(self), typefind);
	gst_element_link(depay, typefind);

	g_object_connect(typefind, "signal::have_type", found_type, self, NULL);

}

static void
new_payload_type(GstElement *demux, guint pt, GstPad *pad, gpointer user_data) {
	GstCaps *caps;
	gint len, i;
	gboolean has_clockrate = FALSE;
{'fraction_non_alphanumeric': 0.1244183469975626, 'fraction_numerical': 0.0006647462884998893, 'mean_word_length': 5.255717255717256, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6688817', 'n_tokens_mistral': 3988, 'n_tokens_neox': 3727, 'n_words': 691}