<commit_before>/*
kmsc - Kurento Media Server C/C++ implementation
Copyright (C) 2012 <NAME>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3
as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <kms-core.h>
#include <rtp/kms-rtp.h>
#include "internal/kms-utils.h"
#include <nice.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))

#define MEDIA_TYPE_DATA "type"
#define STREAM_ID_DATA "stream_id"

static void start_media(KmsRtpReceiver *self);

struct _KmsRtpReceiverPriv {
	GMutex *mutex;

	KmsSessionSpec *local_spec;

	NiceAgent *audio_agent;
	NiceAgent *video_agent;

	gint audio_port;
	gint video_port;
	gint audio_fd;
	gint video_fd;
};

enum {
	PROP_0,

	PROP_LOCAL_SPEC,
	PROP_AUDIO_FD,
	PROP_VIDEO_FD,
	PROP_AUDIO_AGENT,
	PROP_VIDEO_AGENT,
};

G_DEFINE_TYPE(KmsRtpReceiver, kms_rtp_receiver, KMS_TYPE_MEDIA_HANDLER_SRC)

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

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

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;
	}
}

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);
			if (self->priv->local_spec != NULL) {
				g_warn_if_reached();
				UNLOCK(self);
				return;
			}
			dispose_local_spec(self);
			self->priv->local_spec = g_value_dup_object(value);
			if (self->priv->local_spec != NULL)
				start_media(self);
			UNLOCK(self);
			break;
		case PROP_AUDIO_AGENT:
			LOCK(self);
			dispose_audio_agent(self);
			self->priv->audio_agent = g_value_dup_object(value);
			UNLOCK(self);
			break;
		case PROP_VIDEO_AGENT:
			LOCK(self);
			dispose_video_agent(self);
			self->priv->video_agent = 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;
		case PROP_AUDIO_FD:
			LOCK(self);
			g_value_set_int(value, self->priv->audio_fd);
			UNLOCK(self);
			break;
		case PROP_VIDEO_FD:
			LOCK(self);
			g_value_set_int(value, self->priv->video_fd);
			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(KmsMediaSpec *media){
	GSList *list = NULL;
	gint i;

	for (i = 0; i < media->payloads->len; i++) {
		KmsPayload *aux;

		aux = media->payloads->pdata[i];
		list = g_slist_prepend(list, aux);
	}

	return list;
}

static gint
compare_pay_pt(gconstpointer ppay, gconstpointer ppt) {
	KmsPayload *pay = (gpointer) ppay;

	if (!pay->__isset_rtp || pay->rtp == NULL)
		return -1;

	return pay->rtp->id - (*(int *)ppt);
}

static GstCaps*
get_caps_for_pt(KmsRtpReceiver *self, guint pt) {
	KmsSessionSpec *spec;
	GstCaps *caps = NULL;
	gint i;

	LOCK(self);
	spec = self->priv->local_spec;

	if (spec != NULL)
		goto end;

	for (i = 0; i < spec->medias->len; i++) {
		KmsMediaSpec *media;

		media = spec->medias->pdata[i];

		if (g_hash_table_size(media->type) == 1) {
			GSList *payloads, *l;

			payloads = get_pay_list(media);

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

			if (l != NULL) {
				caps = kms_payload_to_caps(l->data, media);
			}

			g_slist_free(payloads);

			if (caps != NULL)
				goto end;
		}<commit_msg>Fix condition to receive media correctly<commit_after>/*
kmsc - Kurento Media Server C/C++ implementation
Copyright (C) 2012 Tikal Technologies

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3
as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <kms-core.h>
#include <rtp/kms-rtp.h>
#include "internal/kms-utils.h"
#include <nice.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))

#define MEDIA_TYPE_DATA "type"
#define STREAM_ID_DATA "stream_id"

static void start_media(KmsRtpReceiver *self);

struct _KmsRtpReceiverPriv {
	GMutex *mutex;

	KmsSessionSpec *local_spec;

	NiceAgent *audio_agent;
	NiceAgent *video_agent;

	gint audio_port;
	gint video_port;
	gint audio_fd;
	gint video_fd;
};

enum {
	PROP_0,

	PROP_LOCAL_SPEC,
	PROP_AUDIO_FD,
	PROP_VIDEO_FD,
	PROP_AUDIO_AGENT,
	PROP_VIDEO_AGENT,
};

G_DEFINE_TYPE(KmsRtpReceiver, kms_rtp_receiver, KMS_TYPE_MEDIA_HANDLER_SRC)

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

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

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;
	}
}

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);
			if (self->priv->local_spec != NULL) {
				g_warn_if_reached();
				UNLOCK(self);
				return;
			}
			dispose_local_spec(self);
			self->priv->local_spec = g_value_dup_object(value);
			if (self->priv->local_spec != NULL)
				start_media(self);
			UNLOCK(self);
			break;
		case PROP_AUDIO_AGENT:
			LOCK(self);
			dispose_audio_agent(self);
			self->priv->audio_agent = g_value_dup_object(value);
			UNLOCK(self);
			break;
		case PROP_VIDEO_AGENT:
			LOCK(self);
			dispose_video_agent(self);
			self->priv->video_agent = 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;
		case PROP_AUDIO_FD:
			LOCK(self);
			g_value_set_int(value, self->priv->audio_fd);
			UNLOCK(self);
			break;
		case PROP_VIDEO_FD:
			LOCK(self);
			g_value_set_int(value, self->priv->video_fd);
			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(KmsMediaSpec *media){
	GSList *list = NULL;
	gint i;

	for (i = 0; i < media->payloads->len; i++) {
		KmsPayload *aux;

		aux = media->payloads->pdata[i];
		list = g_slist_prepend(list, aux);
	}

	return list;
}

static gint
compare_pay_pt(gconstpointer ppay, gconstpointer ppt) {
	KmsPayload *pay = (gpointer) ppay;

	if (!pay->__isset_rtp || pay->rtp == NULL)
		return -1;

	return pay->rtp->id - (*(int *)ppt);
}

static GstCaps*
get_caps_for_pt(KmsRtpReceiver *self, guint pt) {
	KmsSessionSpec *spec;
	GstCaps *caps = NULL;
	gint i;

	LOCK(self);
	spec = self->priv->local_spec;

	if (spec == NULL)
		goto end;

	for (i = 0; i < spec->medias->len; i++) {
		KmsMediaSpec *media;

		media = spec->medias->pdata[i];

		if (g_hash_table_size(media->type) == 1) {
			GSList *payloads, *l;

			payloads = get_pay_list(media);

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

			if (l != NULL) {
				caps = kms_payload_to_caps(l->data, media);
			}

			g_slist_free(payloads);

			if (caps != NULL)
				goto end;
		}
{'fraction_non_alphanumeric': 0.12327176781002638, 'fraction_numerical': 0.0021108179419525065, 'mean_word_length': 4.499709808473592, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 120, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '2103498', 'n_tokens_mistral': 3974, 'n_tokens_neox': 3619, 'n_words': 796}