Mercurial > pidgin
annotate libpurple/media/codec.c @ 32819:2c6510167895 default tip
propagate from branch 'im.pidgin.pidgin.2.x.y' (head 3315c5dfbd0ad16511bdcf865e5b07c02d07df24)
to branch 'im.pidgin.pidgin' (head cbd1eda6bcbf0565ae7766396bb8f6f419cb6a9a)
| author | Elliott Sales de Andrade <qulogic@pidgin.im> |
|---|---|
| date | Sat, 02 Jun 2012 02:30:49 +0000 |
| parents | a8cc50c2279f |
| children |
| rev | line source |
|---|---|
| 29144 | 1 /** |
| 2 * @file codec.c Codec for Media API | |
| 3 * @ingroup core | |
| 4 */ | |
| 5 | |
| 6 /* purple | |
| 7 * | |
| 8 * Purple is the legal property of its developers, whose names are too numerous | |
| 9 * to list here. Please refer to the COPYRIGHT file distributed with this | |
| 10 * source distribution. | |
| 11 * | |
| 12 * This program is free software; you can redistribute it and/or modify | |
| 13 * it under the terms of the GNU General Public License as published by | |
| 14 * the Free Software Foundation; either version 2 of the License, or | |
| 15 * (at your option) any later version. | |
| 16 * | |
| 17 * This program is distributed in the hope that it will be useful, | |
| 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 20 * GNU General Public License for more details. | |
| 21 * | |
| 22 * You should have received a copy of the GNU General Public License | |
| 23 * along with this program; if not, write to the Free Software | |
| 24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA | |
| 25 */ | |
| 26 | |
| 27 #include "codec.h" | |
| 28 | |
| 29 /** @copydoc _PurpleMediaCodecClass */ | |
| 30 typedef struct _PurpleMediaCodecClass PurpleMediaCodecClass; | |
| 31 /** @copydoc _PurpleMediaCodecPrivate */ | |
| 32 typedef struct _PurpleMediaCodecPrivate PurpleMediaCodecPrivate; | |
| 33 | |
| 34 #define PURPLE_MEDIA_CODEC_GET_PRIVATE(obj) \ | |
| 35 (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ | |
| 36 PURPLE_TYPE_MEDIA_CODEC, PurpleMediaCodecPrivate)) | |
| 37 | |
| 38 struct _PurpleMediaCodecClass | |
| 39 { | |
| 40 GObjectClass parent_class; | |
| 41 }; | |
| 42 | |
| 43 struct _PurpleMediaCodec | |
| 44 { | |
| 45 GObject parent; | |
| 46 }; | |
| 47 | |
| 48 G_DEFINE_TYPE(PurpleMediaCodec, purple_media_codec, G_TYPE_OBJECT); | |
| 49 | |
| 50 struct _PurpleMediaCodecPrivate | |
| 51 { | |
| 52 gint id; | |
| 53 char *encoding_name; | |
| 54 PurpleMediaSessionType media_type; | |
| 55 guint clock_rate; | |
| 56 guint channels; | |
| 57 GList *optional_params; | |
| 58 }; | |
| 59 | |
| 60 enum { | |
| 61 PROP_CODEC_0, | |
| 62 PROP_ID, | |
| 63 PROP_ENCODING_NAME, | |
| 64 PROP_MEDIA_TYPE, | |
| 65 PROP_CLOCK_RATE, | |
| 66 PROP_CHANNELS, | |
| 67 PROP_OPTIONAL_PARAMS, | |
| 68 }; | |
| 69 | |
| 70 static void | |
| 71 purple_media_codec_init(PurpleMediaCodec *info) | |
| 72 { | |
| 73 PurpleMediaCodecPrivate *priv = | |
| 74 PURPLE_MEDIA_CODEC_GET_PRIVATE(info); | |
| 75 priv->encoding_name = NULL; | |
| 76 priv->optional_params = NULL; | |
| 77 } | |
| 78 | |
| 79 static void | |
| 80 purple_media_codec_finalize(GObject *info) | |
| 81 { | |
| 82 PurpleMediaCodecPrivate *priv = | |
| 83 PURPLE_MEDIA_CODEC_GET_PRIVATE(info); | |
| 84 g_free(priv->encoding_name); | |
| 85 for (; priv->optional_params; priv->optional_params = | |
| 30439 | 86 g_list_delete_link(priv->optional_params, priv->optional_params)) { |
| 87 PurpleKeyValuePair *param = priv->optional_params->data; | |
| 88 g_free(param->key); | |
| 89 g_free(param->value); | |
| 90 g_free(param); | |
| 29144 | 91 } |
| 92 } | |
| 93 | |
| 94 static void | |
| 95 purple_media_codec_set_property (GObject *object, guint prop_id, | |
| 96 const GValue *value, GParamSpec *pspec) | |
| 97 { | |
| 98 PurpleMediaCodecPrivate *priv; | |
| 99 g_return_if_fail(PURPLE_IS_MEDIA_CODEC(object)); | |
| 100 | |
| 101 priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(object); | |
| 102 | |
| 103 switch (prop_id) { | |
| 104 case PROP_ID: | |
| 105 priv->id = g_value_get_uint(value); | |
| 106 break; | |
| 107 case PROP_ENCODING_NAME: | |
| 108 g_free(priv->encoding_name); | |
| 109 priv->encoding_name = g_value_dup_string(value); | |
| 110 break; | |
| 111 case PROP_MEDIA_TYPE: | |
| 112 priv->media_type = g_value_get_flags(value); | |
| 113 break; | |
| 114 case PROP_CLOCK_RATE: | |
| 115 priv->clock_rate = g_value_get_uint(value); | |
| 116 break; | |
| 117 case PROP_CHANNELS: | |
| 118 priv->channels = g_value_get_uint(value); | |
| 119 break; | |
| 120 case PROP_OPTIONAL_PARAMS: | |
| 121 priv->optional_params = g_value_get_pointer(value); | |
| 122 break; | |
|
31086
a8cc50c2279f
Remove trailing whitespace
Richard Laager <rlaager@wiktel.com>
parents:
30439
diff
changeset
|
123 default: |
| 29144 | 124 G_OBJECT_WARN_INVALID_PROPERTY_ID( |
| 125 object, prop_id, pspec); | |
| 126 break; | |
| 127 } | |
| 128 } | |
| 129 | |
| 130 static void | |
| 131 purple_media_codec_get_property (GObject *object, guint prop_id, | |
| 132 GValue *value, GParamSpec *pspec) | |
| 133 { | |
| 134 PurpleMediaCodecPrivate *priv; | |
| 135 g_return_if_fail(PURPLE_IS_MEDIA_CODEC(object)); | |
|
31086
a8cc50c2279f
Remove trailing whitespace
Richard Laager <rlaager@wiktel.com>
parents:
30439
diff
changeset
|
136 |
| 29144 | 137 priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(object); |
| 138 | |
| 139 switch (prop_id) { | |
| 140 case PROP_ID: | |
| 141 g_value_set_uint(value, priv->id); | |
| 142 break; | |
| 143 case PROP_ENCODING_NAME: | |
| 144 g_value_set_string(value, priv->encoding_name); | |
| 145 break; | |
| 146 case PROP_MEDIA_TYPE: | |
| 147 g_value_set_flags(value, priv->media_type); | |
| 148 break; | |
| 149 case PROP_CLOCK_RATE: | |
| 150 g_value_set_uint(value, priv->clock_rate); | |
| 151 break; | |
| 152 case PROP_CHANNELS: | |
| 153 g_value_set_uint(value, priv->channels); | |
| 154 break; | |
| 155 case PROP_OPTIONAL_PARAMS: | |
| 156 g_value_set_pointer(value, priv->optional_params); | |
| 157 break; | |
|
31086
a8cc50c2279f
Remove trailing whitespace
Richard Laager <rlaager@wiktel.com>
parents:
30439
diff
changeset
|
158 default: |
| 29144 | 159 G_OBJECT_WARN_INVALID_PROPERTY_ID( |
| 160 object, prop_id, pspec); | |
| 161 break; | |
| 162 } | |
| 163 } | |
| 164 | |
| 165 static void | |
| 166 purple_media_codec_class_init(PurpleMediaCodecClass *klass) | |
| 167 { | |
| 168 GObjectClass *gobject_class = (GObjectClass*)klass; | |
|
31086
a8cc50c2279f
Remove trailing whitespace
Richard Laager <rlaager@wiktel.com>
parents:
30439
diff
changeset
|
169 |
| 29144 | 170 gobject_class->finalize = purple_media_codec_finalize; |
| 171 gobject_class->set_property = purple_media_codec_set_property; | |
| 172 gobject_class->get_property = purple_media_codec_get_property; | |
| 173 | |
| 174 g_object_class_install_property(gobject_class, PROP_ID, | |
| 175 g_param_spec_uint("id", | |
| 176 "ID", | |
| 177 "The numeric identifier of the codec.", | |
| 178 0, G_MAXUINT, 0, | |
| 179 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); | |
| 180 | |
| 181 g_object_class_install_property(gobject_class, PROP_ENCODING_NAME, | |
| 182 g_param_spec_string("encoding-name", | |
| 183 "Encoding Name", | |
| 184 "The name of the codec.", | |
| 185 NULL, | |
| 186 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); | |
| 187 | |
| 188 g_object_class_install_property(gobject_class, PROP_MEDIA_TYPE, | |
| 189 g_param_spec_flags("media-type", | |
| 190 "Media Type", | |
| 191 "Whether this is an audio of video codec.", | |
| 192 PURPLE_TYPE_MEDIA_SESSION_TYPE, | |
| 193 PURPLE_MEDIA_NONE, | |
| 194 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); | |
| 195 | |
| 196 g_object_class_install_property(gobject_class, PROP_CLOCK_RATE, | |
| 197 g_param_spec_uint("clock-rate", | |
| 198 "Create Callback", | |
| 199 "The function called to create this element.", | |
| 200 0, G_MAXUINT, 0, | |
| 201 G_PARAM_READWRITE)); | |
| 202 | |
| 203 g_object_class_install_property(gobject_class, PROP_CHANNELS, | |
| 204 g_param_spec_uint("channels", | |
| 205 "Channels", | |
| 206 "The number of channels in this codec.", | |
| 207 0, G_MAXUINT, 0, | |
| 208 G_PARAM_READWRITE)); | |
| 209 g_object_class_install_property(gobject_class, PROP_OPTIONAL_PARAMS, | |
| 210 g_param_spec_pointer("optional-params", | |
| 211 "Optional Params", | |
| 212 "A list of optional parameters for the codec.", | |
| 213 G_PARAM_READWRITE)); | |
| 214 | |
| 215 g_type_class_add_private(klass, sizeof(PurpleMediaCodecPrivate)); | |
| 216 } | |
| 217 | |
| 218 PurpleMediaCodec * | |
| 219 purple_media_codec_new(int id, const char *encoding_name, | |
| 220 PurpleMediaSessionType media_type, guint clock_rate) | |
| 221 { | |
| 222 PurpleMediaCodec *codec = | |
| 223 g_object_new(PURPLE_TYPE_MEDIA_CODEC, | |
| 224 "id", id, | |
| 225 "encoding_name", encoding_name, | |
| 226 "media_type", media_type, | |
| 227 "clock-rate", clock_rate, NULL); | |
| 228 return codec; | |
| 229 } | |
| 230 | |
| 231 guint | |
| 232 purple_media_codec_get_id(PurpleMediaCodec *codec) | |
| 233 { | |
| 234 guint id; | |
| 235 g_return_val_if_fail(PURPLE_IS_MEDIA_CODEC(codec), 0); | |
| 236 g_object_get(codec, "id", &id, NULL); | |
| 237 return id; | |
| 238 } | |
| 239 | |
| 240 gchar * | |
| 241 purple_media_codec_get_encoding_name(PurpleMediaCodec *codec) | |
| 242 { | |
| 243 gchar *name; | |
| 244 g_return_val_if_fail(PURPLE_IS_MEDIA_CODEC(codec), NULL); | |
| 245 g_object_get(codec, "encoding-name", &name, NULL); | |
| 246 return name; | |
| 247 } | |
| 248 | |
| 249 guint | |
| 250 purple_media_codec_get_clock_rate(PurpleMediaCodec *codec) | |
| 251 { | |
| 252 guint clock_rate; | |
| 253 g_return_val_if_fail(PURPLE_IS_MEDIA_CODEC(codec), 0); | |
| 254 g_object_get(codec, "clock-rate", &clock_rate, NULL); | |
| 255 return clock_rate; | |
| 256 } | |
| 257 | |
| 258 guint | |
| 259 purple_media_codec_get_channels(PurpleMediaCodec *codec) | |
| 260 { | |
| 261 guint channels; | |
| 262 g_return_val_if_fail(PURPLE_IS_MEDIA_CODEC(codec), 0); | |
| 263 g_object_get(codec, "channels", &channels, NULL); | |
| 264 return channels; | |
| 265 } | |
| 266 | |
| 267 GList * | |
| 268 purple_media_codec_get_optional_parameters(PurpleMediaCodec *codec) | |
| 269 { | |
| 270 GList *optional_params; | |
| 271 g_return_val_if_fail(PURPLE_IS_MEDIA_CODEC(codec), NULL); | |
| 272 g_object_get(codec, "optional-params", &optional_params, NULL); | |
| 273 return optional_params; | |
| 274 } | |
| 275 | |
| 276 void | |
| 277 purple_media_codec_add_optional_parameter(PurpleMediaCodec *codec, | |
| 278 const gchar *name, const gchar *value) | |
| 279 { | |
| 280 PurpleMediaCodecPrivate *priv; | |
| 281 PurpleKeyValuePair *new_param; | |
| 282 | |
| 283 g_return_if_fail(codec != NULL); | |
| 284 g_return_if_fail(name != NULL && value != NULL); | |
| 285 | |
| 286 priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(codec); | |
| 287 | |
| 288 new_param = g_new0(PurpleKeyValuePair, 1); | |
| 289 new_param->key = g_strdup(name); | |
| 290 new_param->value = g_strdup(value); | |
| 291 priv->optional_params = g_list_append( | |
| 292 priv->optional_params, new_param); | |
| 293 } | |
| 294 | |
| 295 void | |
| 296 purple_media_codec_remove_optional_parameter(PurpleMediaCodec *codec, | |
| 297 PurpleKeyValuePair *param) | |
| 298 { | |
| 299 PurpleMediaCodecPrivate *priv; | |
| 300 | |
| 301 g_return_if_fail(codec != NULL && param != NULL); | |
| 302 | |
| 303 priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(codec); | |
| 304 | |
| 305 g_free(param->key); | |
| 306 g_free(param->value); | |
| 307 | |
| 308 priv->optional_params = | |
| 309 g_list_remove(priv->optional_params, param); | |
| 30439 | 310 g_free(param); |
| 29144 | 311 } |
| 312 | |
| 313 PurpleKeyValuePair * | |
| 314 purple_media_codec_get_optional_parameter(PurpleMediaCodec *codec, | |
| 315 const gchar *name, const gchar *value) | |
| 316 { | |
| 317 PurpleMediaCodecPrivate *priv; | |
| 318 GList *iter; | |
| 319 | |
| 320 g_return_val_if_fail(codec != NULL, NULL); | |
| 321 g_return_val_if_fail(name != NULL, NULL); | |
| 322 | |
| 323 priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(codec); | |
| 324 | |
| 325 for (iter = priv->optional_params; iter; iter = g_list_next(iter)) { | |
| 326 PurpleKeyValuePair *param = iter->data; | |
| 327 if (!g_ascii_strcasecmp(param->key, name) && | |
| 328 (value == NULL || | |
| 329 !g_ascii_strcasecmp(param->value, value))) | |
| 330 return param; | |
| 331 } | |
| 332 | |
| 333 return NULL; | |
| 334 } | |
| 335 | |
| 336 PurpleMediaCodec * | |
| 337 purple_media_codec_copy(PurpleMediaCodec *codec) | |
| 338 { | |
| 339 PurpleMediaCodecPrivate *priv; | |
| 340 PurpleMediaCodec *new_codec; | |
| 341 GList *iter; | |
| 342 | |
| 343 if (codec == NULL) | |
| 344 return NULL; | |
| 345 | |
| 346 priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(codec); | |
| 347 | |
| 348 new_codec = purple_media_codec_new(priv->id, priv->encoding_name, | |
| 349 priv->media_type, priv->clock_rate); | |
| 350 g_object_set(codec, "channels", priv->channels, NULL); | |
| 351 | |
| 352 for (iter = priv->optional_params; iter; iter = g_list_next(iter)) { | |
| 353 PurpleKeyValuePair *param = | |
| 354 (PurpleKeyValuePair*)iter->data; | |
| 355 purple_media_codec_add_optional_parameter(new_codec, | |
| 356 param->key, param->value); | |
| 357 } | |
| 358 | |
| 359 return new_codec; | |
| 360 } | |
| 361 | |
| 362 GList * | |
| 363 purple_media_codec_list_copy(GList *codecs) | |
| 364 { | |
| 365 GList *new_list = NULL; | |
| 366 | |
| 367 for (; codecs; codecs = g_list_next(codecs)) { | |
| 368 new_list = g_list_prepend(new_list, | |
| 369 purple_media_codec_copy(codecs->data)); | |
| 370 } | |
| 371 | |
| 372 new_list = g_list_reverse(new_list); | |
| 373 return new_list; | |
| 374 } | |
| 375 | |
| 376 void | |
| 377 purple_media_codec_list_free(GList *codecs) | |
| 378 { | |
| 379 for (; codecs; codecs = | |
| 380 g_list_delete_link(codecs, codecs)) { | |
| 381 g_object_unref(codecs->data); | |
| 382 } | |
| 383 } | |
| 384 | |
| 385 gchar * | |
| 386 purple_media_codec_to_string(const PurpleMediaCodec *codec) | |
| 387 { | |
| 388 PurpleMediaCodecPrivate *priv; | |
| 389 GString *string = NULL; | |
| 390 GList *item; | |
| 391 gchar *charstring; | |
| 392 const gchar *media_type_str = NULL; | |
| 393 | |
| 394 if (codec == NULL) | |
| 395 return g_strdup("(NULL)"); | |
| 396 | |
| 397 priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(codec); | |
| 398 | |
| 399 string = g_string_new(""); | |
| 400 | |
| 401 if (priv->media_type & PURPLE_MEDIA_AUDIO) | |
| 402 media_type_str = "audio"; | |
| 403 else if (priv->media_type & PURPLE_MEDIA_VIDEO) | |
| 404 media_type_str = "video"; | |
| 405 | |
| 406 g_string_printf(string, "%d: %s %s clock:%d channels:%d", priv->id, | |
| 407 media_type_str, priv->encoding_name, | |
| 408 priv->clock_rate, priv->channels); | |
| 409 | |
| 410 for (item = priv->optional_params; item; item = g_list_next (item)) { | |
| 411 PurpleKeyValuePair *param = item->data; | |
| 412 g_string_append_printf (string, " %s=%s", | |
| 413 param->key, (gchar *)param->value); | |
| 414 } | |
| 415 | |
| 416 charstring = string->str; | |
| 417 g_string_free (string, FALSE); | |
| 418 | |
| 419 return charstring; | |
| 420 } | |
| 421 |
