From 8f656be6a17b7dfd015c404791f541037abfbdcd Mon Sep 17 00:00:00 2001 From: Michael Ruprecht Date: Thu, 2 Apr 2009 04:06:07 +0000 Subject: Hide and gobjectify PurpleMediaCodec. --- libpurple/media.c | 363 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 306 insertions(+), 57 deletions(-) (limited to 'libpurple/media.c') diff --git a/libpurple/media.c b/libpurple/media.c index aefccf2369..cbcaac26d4 100644 --- a/libpurple/media.c +++ b/libpurple/media.c @@ -45,6 +45,10 @@ typedef struct _PurpleMediaSession PurpleMediaSession; /** @copydoc _PurpleMediaStream */ typedef struct _PurpleMediaStream PurpleMediaStream; +/** @copydoc _PurpleMediaCodecClass */ +typedef struct _PurpleMediaCodecClass PurpleMediaCodecClass; +/** @copydoc _PurpleMediaCodecPrivate */ +typedef struct _PurpleMediaCodecPrivate PurpleMediaCodecPrivate; /** The media class */ struct _PurpleMediaClass @@ -115,6 +119,7 @@ struct _PurpleMediaPrivate #ifdef USE_VV #define PURPLE_MEDIA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_MEDIA, PurpleMediaPrivate)) +#define PURPLE_MEDIA_CODEC_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_MEDIA_CODEC, PurpleMediaCodecPrivate)) static void purple_media_class_init (PurpleMediaClass *klass); static void purple_media_init (PurpleMedia *media); @@ -159,6 +164,39 @@ enum { }; #endif + +/* + * PurpleMediaElementType + */ + +GType +purple_media_session_type_get_type() +{ + static GType type = 0; + if (type == 0) { + static const GFlagsValue values[] = { + { PURPLE_MEDIA_NONE, + "PURPLE_MEDIA_NONE", "none" }, + { PURPLE_MEDIA_RECV_AUDIO, + "PURPLE_MEDIA_RECV_AUDIO", "recv-audio" }, + { PURPLE_MEDIA_SEND_AUDIO, + "PURPLE_MEDIA_SEND_AUDIO", "send-audio" }, + { PURPLE_MEDIA_RECV_VIDEO, + "PURPLE_MEDIA_RECV_VIDEO", "recv-video" }, + { PURPLE_MEDIA_SEND_VIDEO, + "PURPLE_MEDIA_SEND_VIDEO", "send-audio" }, + { PURPLE_MEDIA_AUDIO, + "PURPLE_MEDIA_AUDIO", "audio" }, + { PURPLE_MEDIA_VIDEO, + "PURPLE_MEDIA_VIDEO", "video" }, + { 0, NULL, NULL } + }; + type = g_flags_register_static( + "PurpleMediaSessionType", values); + } + return type; +} + GType purple_media_get_type() { @@ -749,46 +787,284 @@ purple_media_from_fs(FsMediaType type, FsStreamDirection direction) } #endif +/* + * PurpleMediaCodec + */ + +struct _PurpleMediaCodecClass +{ + GObjectClass parent_class; +}; + +struct _PurpleMediaCodec +{ + GObject parent; +}; + +struct _PurpleMediaCodecPrivate +{ + gint id; + char *encoding_name; + PurpleMediaSessionType media_type; + guint clock_rate; + guint channels; + GList *optional_params; +}; + +enum { + PROP_CODEC_0, + PROP_ID, + PROP_ENCODING_NAME, + PROP_MEDIA_TYPE, + PROP_CLOCK_RATE, + PROP_CHANNELS, + PROP_OPTIONAL_PARAMS, +}; + +static void +purple_media_codec_init(PurpleMediaCodec *info) +{ + PurpleMediaCodecPrivate *priv = + PURPLE_MEDIA_CODEC_GET_PRIVATE(info); + priv->encoding_name = NULL; + priv->optional_params = NULL; +} + +static void +purple_media_codec_finalize(GObject *info) +{ + PurpleMediaCodecPrivate *priv = + PURPLE_MEDIA_CODEC_GET_PRIVATE(info); + g_free(priv->encoding_name); + for (; priv->optional_params; priv->optional_params = + g_list_delete_link(priv->optional_params, + priv->optional_params)) { + g_free(priv->optional_params->data); + } +} + +static void +purple_media_codec_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + PurpleMediaCodecPrivate *priv; + g_return_if_fail(PURPLE_IS_MEDIA_CODEC(object)); + + priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_ID: + priv->id = g_value_get_uint(value); + break; + case PROP_ENCODING_NAME: + g_free(priv->encoding_name); + priv->encoding_name = g_value_dup_string(value); + break; + case PROP_MEDIA_TYPE: + priv->media_type = g_value_get_flags(value); + break; + case PROP_CLOCK_RATE: + priv->clock_rate = g_value_get_uint(value); + break; + case PROP_CHANNELS: + priv->channels = g_value_get_uint(value); + break; + case PROP_OPTIONAL_PARAMS: + priv->optional_params = g_value_get_pointer(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID( + object, prop_id, pspec); + break; + } +} + +static void +purple_media_codec_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + PurpleMediaCodecPrivate *priv; + g_return_if_fail(PURPLE_IS_MEDIA_CODEC(object)); + + priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_ID: + g_value_set_uint(value, priv->id); + break; + case PROP_ENCODING_NAME: + g_value_set_string(value, priv->encoding_name); + break; + case PROP_MEDIA_TYPE: + g_value_set_flags(value, priv->media_type); + break; + case PROP_CLOCK_RATE: + g_value_set_uint(value, priv->clock_rate); + break; + case PROP_CHANNELS: + g_value_set_uint(value, priv->channels); + break; + case PROP_OPTIONAL_PARAMS: + g_value_set_pointer(value, priv->optional_params); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID( + object, prop_id, pspec); + break; + } +} + +static void +purple_media_codec_class_init(PurpleMediaCodecClass *klass) +{ + GObjectClass *gobject_class = (GObjectClass*)klass; + + gobject_class->finalize = purple_media_codec_finalize; + gobject_class->set_property = purple_media_codec_set_property; + gobject_class->get_property = purple_media_codec_get_property; + + g_object_class_install_property(gobject_class, PROP_ID, + g_param_spec_uint("id", + "ID", + "The numeric identifier of the codec.", + 0, G_MAXUINT, 0, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); + + g_object_class_install_property(gobject_class, PROP_ENCODING_NAME, + g_param_spec_string("encoding-name", + "Encoding Name", + "The name of the codec.", + NULL, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); + + g_object_class_install_property(gobject_class, PROP_MEDIA_TYPE, + g_param_spec_flags("media-type", + "Media Type", + "Whether this is an audio of video codec.", + PURPLE_TYPE_MEDIA_SESSION_TYPE, + PURPLE_MEDIA_NONE, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); + + g_object_class_install_property(gobject_class, PROP_CLOCK_RATE, + g_param_spec_uint("clock-rate", + "Create Callback", + "The function called to create this element.", + 0, G_MAXUINT, 0, + G_PARAM_READWRITE)); + + g_object_class_install_property(gobject_class, PROP_CHANNELS, + g_param_spec_uint("channels", + "Channels", + "The number of channels in this codec.", + 0, G_MAXUINT, 0, + G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, PROP_OPTIONAL_PARAMS, + g_param_spec_pointer("optional-params", + "Optional Params", + "A list of optional parameters for the codec.", + G_PARAM_READWRITE)); + + g_type_class_add_private(klass, sizeof(PurpleMediaCodecPrivate)); +} + +G_DEFINE_TYPE(PurpleMediaCodec, + purple_media_codec, G_TYPE_OBJECT); + +guint +purple_media_codec_get_id(PurpleMediaCodec *codec) +{ + guint id; + g_return_val_if_fail(PURPLE_IS_MEDIA_CODEC(codec), 0); + g_object_get(codec, "id", &id, NULL); + return id; +} + +gchar * +purple_media_codec_get_encoding_name(PurpleMediaCodec *codec) +{ + gchar *name; + g_return_val_if_fail(PURPLE_IS_MEDIA_CODEC(codec), NULL); + g_object_get(codec, "encoding-name", &name, NULL); + return name; +} + +guint +purple_media_codec_get_clock_rate(PurpleMediaCodec *codec) +{ + guint clock_rate; + g_return_val_if_fail(PURPLE_IS_MEDIA_CODEC(codec), 0); + g_object_get(codec, "clock-rate", &clock_rate, NULL); + return clock_rate; +} + +guint +purple_media_codec_get_channels(PurpleMediaCodec *codec) +{ + guint channels; + g_return_val_if_fail(PURPLE_IS_MEDIA_CODEC(codec), 0); + g_object_get(codec, "channels", &channels, NULL); + return channels; +} + +GList * +purple_media_codec_get_optional_parameters(PurpleMediaCodec *codec) +{ + GList *optional_params; + g_return_val_if_fail(PURPLE_IS_MEDIA_CODEC(codec), NULL); + g_object_get(codec, "optional-params", &optional_params, NULL); + return optional_params; +} + void purple_media_codec_add_optional_parameter(PurpleMediaCodec *codec, const gchar *name, const gchar *value) { + PurpleMediaCodecPrivate *priv; PurpleKeyValuePair *new_param; g_return_if_fail(codec != NULL); g_return_if_fail(name != NULL && value != NULL); + priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(codec); + new_param = g_new0(PurpleKeyValuePair, 1); new_param->key = g_strdup(name); new_param->value = g_strdup(value); - codec->optional_params = g_list_append( - codec->optional_params, new_param); + priv->optional_params = g_list_append( + priv->optional_params, new_param); } void purple_media_codec_remove_optional_parameter(PurpleMediaCodec *codec, PurpleKeyValuePair *param) { + PurpleMediaCodecPrivate *priv; + g_return_if_fail(codec != NULL && param != NULL); + priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(codec); + g_free(param->key); g_free(param->value); g_free(param); - codec->optional_params = - g_list_remove(codec->optional_params, param); + priv->optional_params = + g_list_remove(priv->optional_params, param); } PurpleKeyValuePair * purple_media_codec_get_optional_parameter(PurpleMediaCodec *codec, const gchar *name, const gchar *value) { + PurpleMediaCodecPrivate *priv; GList *iter; g_return_val_if_fail(codec != NULL, NULL); g_return_val_if_fail(name != NULL, NULL); - for (iter = codec->optional_params; iter; iter = g_list_next(iter)) { + priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(codec); + + for (iter = priv->optional_params; iter; iter = g_list_next(iter)) { PurpleKeyValuePair *param = iter->data; if (!g_ascii_strcasecmp(param->key, name) && (value == NULL || @@ -803,29 +1079,32 @@ PurpleMediaCodec * purple_media_codec_new(int id, const char *encoding_name, PurpleMediaSessionType media_type, guint clock_rate) { - PurpleMediaCodec *codec = g_new0(PurpleMediaCodec, 1); - - codec->id = id; - codec->encoding_name = g_strdup(encoding_name); - codec->media_type = media_type; - codec->clock_rate = clock_rate; + PurpleMediaCodec *codec = + g_object_new(PURPLE_TYPE_MEDIA_CODEC, + "id", id, + "encoding_name", encoding_name, + "media_type", media_type, + "clock-rate", clock_rate, NULL); return codec; } static PurpleMediaCodec * purple_media_codec_copy(PurpleMediaCodec *codec) { + PurpleMediaCodecPrivate *priv; PurpleMediaCodec *new_codec; GList *iter; if (codec == NULL) return NULL; - new_codec = purple_media_codec_new(codec->id, codec->encoding_name, - codec->media_type, codec->clock_rate); - new_codec->channels = codec->channels; + priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(codec); - for (iter = codec->optional_params; iter; iter = g_list_next(iter)) { + new_codec = purple_media_codec_new(priv->id, priv->encoding_name, + priv->media_type, priv->clock_rate); + g_object_set(codec, "channels", priv->channels, NULL); + + for (iter = priv->optional_params; iter; iter = g_list_next(iter)) { PurpleKeyValuePair *param = (PurpleKeyValuePair*)iter->data; purple_media_codec_add_optional_parameter(new_codec, @@ -835,40 +1114,25 @@ purple_media_codec_copy(PurpleMediaCodec *codec) return new_codec; } -static void -purple_media_codec_free(PurpleMediaCodec *codec) -{ - if (codec == NULL) - return; - - g_free(codec->encoding_name); - - for (; codec->optional_params; codec->optional_params = - g_list_delete_link(codec->optional_params, - codec->optional_params)) { - purple_media_codec_remove_optional_parameter(codec, - codec->optional_params->data); - } - - g_free(codec); -} - #ifdef USE_VV static FsCodec * purple_media_codec_to_fs(const PurpleMediaCodec *codec) { + PurpleMediaCodecPrivate *priv; FsCodec *new_codec; GList *iter; if (codec == NULL) return NULL; - new_codec = fs_codec_new(codec->id, codec->encoding_name, - purple_media_to_fs_media_type(codec->media_type), - codec->clock_rate); - new_codec->channels = codec->channels; + priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(codec); - for (iter = codec->optional_params; iter; iter = g_list_next(iter)) { + new_codec = fs_codec_new(priv->id, priv->encoding_name, + purple_media_to_fs_media_type(priv->media_type), + priv->clock_rate); + new_codec->channels = priv->channels; + + for (iter = priv->optional_params; iter; iter = g_list_next(iter)) { PurpleKeyValuePair *param = (PurpleKeyValuePair*)iter->data; fs_codec_add_optional_parameter(new_codec, param->key, param->value); @@ -889,7 +1153,7 @@ purple_media_codec_from_fs(const FsCodec *codec) new_codec = purple_media_codec_new(codec->id, codec->encoding_name, purple_media_from_fs(codec->media_type, FS_DIRECTION_BOTH), codec->clock_rate); - new_codec->channels = codec->channels; + g_object_set(new_codec, "channels", codec->channels, NULL); for (iter = codec->optional_params; iter; iter = g_list_next(iter)) { FsCodecParameter *param = (FsCodecParameter*)iter->data; @@ -952,9 +1216,8 @@ purple_media_codec_list_copy(GList *codecs) GList *new_list = NULL; for (; codecs; codecs = g_list_next(codecs)) { - new_list = g_list_prepend(new_list, g_boxed_copy( - PURPLE_TYPE_MEDIA_CODEC, - codecs->data)); + new_list = g_list_prepend(new_list, + purple_media_codec_copy(codecs->data)); } new_list = g_list_reverse(new_list); @@ -966,24 +1229,10 @@ purple_media_codec_list_free(GList *codecs) { for (; codecs; codecs = g_list_delete_link(codecs, codecs)) { - g_boxed_free(PURPLE_TYPE_MEDIA_CODEC, - codecs->data); + g_object_unref(codecs->data); } } -GType -purple_media_codec_get_type() -{ - static GType type = 0; - - if (type == 0) { - type = g_boxed_type_register_static("PurpleMediaCodec", - (GBoxedCopyFunc)purple_media_codec_copy, - (GBoxedFreeFunc)purple_media_codec_free); - } - return type; -} - #ifdef USE_VV static PurpleMediaSession* purple_media_get_session(PurpleMedia *media, const gchar *sess_id) -- cgit v1.2.1