# HG changeset patch # User Mike Ruprecht # Date 1238645167 0 # Node ID 217574ec2a34dd8cee9dde4b0f169f132e613cfb # Parent f0de2405c2f15c26561d722a6a5041d94a3d14d5 Hide and gobjectify PurpleMediaCodec. diff -r f0de2405c2f1 -r 217574ec2a34 libpurple/media.c --- a/libpurple/media.c Thu Apr 02 01:12:23 2009 +0000 +++ b/libpurple/media.c Thu Apr 02 04:06:07 2009 +0000 @@ -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 @@ #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 @@ }; #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 @@ } #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 @@ 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 @@ 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 @@ 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 @@ 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 @@ { 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) diff -r f0de2405c2f1 -r 217574ec2a34 libpurple/media.h --- a/libpurple/media.h Thu Apr 02 01:12:23 2009 +0000 +++ b/libpurple/media.h Thu Apr 02 04:06:07 2009 +0000 @@ -35,9 +35,16 @@ G_BEGIN_DECLS +#define PURPLE_TYPE_MEDIA_CODEC (purple_media_codec_get_type()) +#define PURPLE_MEDIA_CODEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_MEDIA_CODEC, PurpleMediaCodec)) +#define PURPLE_MEDIA_CODEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_MEDIA_CODEC, PurpleMediaCodec)) +#define PURPLE_IS_MEDIA_CODEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_MEDIA_CODEC)) +#define PURPLE_IS_MEDIA_CODEC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_MEDIA_CODEC)) +#define PURPLE_MEDIA_CODEC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_MEDIA_CODEC, PurpleMediaCodec)) + +#define PURPLE_TYPE_MEDIA_SESSION_TYPE (purple_media_session_type_get_type()) #define PURPLE_TYPE_MEDIA (purple_media_get_type()) #define PURPLE_TYPE_MEDIA_CANDIDATE (purple_media_candidate_get_type()) -#define PURPLE_TYPE_MEDIA_CODEC (purple_media_codec_get_type()) #define PURPLE_MEDIA(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_MEDIA, PurpleMedia)) #define PURPLE_MEDIA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_MEDIA, PurpleMediaClass)) #define PURPLE_IS_MEDIA(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_MEDIA)) @@ -134,21 +141,18 @@ guint ttl; }; -struct _PurpleMediaCodec -{ - gint id; - char *encoding_name; - PurpleMediaSessionType media_type; - guint clock_rate; - guint channels; - GList *optional_params; -}; - #ifdef __cplusplus extern "C" { #endif /** + * Gets the media session type's GType + * + * @return The media session type's GType. + */ +GType purple_media_session_type_get_type(void); + +/** * Gets the media class's GType * * @return The media class's GType. @@ -230,6 +234,12 @@ PurpleMediaCodec *purple_media_codec_new(int id, const char *encoding_name, PurpleMediaSessionType media_type, guint clock_rate); +guint purple_media_codec_get_id(PurpleMediaCodec *codec); +gchar *purple_media_codec_get_encoding_name(PurpleMediaCodec *codec); +guint purple_media_codec_get_clock_rate(PurpleMediaCodec *codec); +guint purple_media_codec_get_channels(PurpleMediaCodec *codec); +GList *purple_media_codec_get_optional_parameters(PurpleMediaCodec *codec); + /** * Creates a string representation of the codec. * diff -r f0de2405c2f1 -r 217574ec2a34 libpurple/protocols/jabber/google.c --- a/libpurple/protocols/jabber/google.c Thu Apr 02 01:12:23 2009 +0000 +++ b/libpurple/protocols/jabber/google.c Thu Apr 02 04:06:07 2009 +0000 @@ -202,13 +202,18 @@ for (iter = codecs; iter; iter = g_list_next(iter)) { PurpleMediaCodec *codec = (PurpleMediaCodec*)iter->data; - gchar *id = g_strdup_printf("%d", codec->id); - gchar *clock_rate = g_strdup_printf("%d", codec->clock_rate); + gchar *id = g_strdup_printf("%d", + purple_media_codec_get_id(codec)); + gchar *encoding_name = + purple_media_codec_get_encoding_name(codec); + gchar *clock_rate = g_strdup_printf("%d", + purple_media_codec_get_clock_rate(codec)); payload = xmlnode_new_child(desc, "payload-type"); xmlnode_set_attrib(payload, "id", id); - xmlnode_set_attrib(payload, "name", codec->encoding_name); + xmlnode_set_attrib(payload, "name", encoding_name); xmlnode_set_attrib(payload, "clockrate", clock_rate); g_free(clock_rate); + g_free(encoding_name); g_free(id); } purple_media_codec_list_free(codecs); diff -r f0de2405c2f1 -r 217574ec2a34 libpurple/protocols/jabber/jingle/rtp.c --- a/libpurple/protocols/jabber/jingle/rtp.c Thu Apr 02 01:12:23 2009 +0000 +++ b/libpurple/protocols/jabber/jingle/rtp.c Thu Apr 02 04:06:07 2009 +0000 @@ -666,20 +666,29 @@ { for (; codecs ; codecs = codecs->next) { PurpleMediaCodec *codec = (PurpleMediaCodec*)codecs->data; - GList *iter = codec->optional_params; - char id[8], clockrate[10], channels[10]; + GList *iter = purple_media_codec_get_optional_parameters(codec); + gchar *id, *name, *clockrate, *channels; gchar *codec_str; xmlnode *payload = xmlnode_new_child(description, "payload-type"); - g_snprintf(id, sizeof(id), "%d", codec->id); - g_snprintf(clockrate, sizeof(clockrate), "%d", codec->clock_rate); - g_snprintf(channels, sizeof(channels), "%d", codec->channels); - - xmlnode_set_attrib(payload, "name", codec->encoding_name); + id = g_strdup_printf("%d", + purple_media_codec_get_id(codec)); + name = purple_media_codec_get_encoding_name(codec); + clockrate = g_strdup_printf("%d", + purple_media_codec_get_clock_rate(codec)); + channels = g_strdup_printf("%d", + purple_media_codec_get_channels(codec)); + + xmlnode_set_attrib(payload, "name", name); xmlnode_set_attrib(payload, "id", id); xmlnode_set_attrib(payload, "clockrate", clockrate); xmlnode_set_attrib(payload, "channels", channels); + g_free(channels); + g_free(clockrate); + g_free(name); + g_free(id); + for (; iter; iter = g_list_next(iter)) { PurpleKeyValuePair *mparam = iter->data; xmlnode *param = xmlnode_new_child(payload, "parameter");