Mercurial > pidgin.yaz
annotate libpurple/media/codec.c @ 31749:4f414608eaad
propagate from branch 'im.pidgin.pidgin.mxit' (head 342293440b7089597815dac27b11677a4cef7254)
to branch 'im.pidgin.pidgin' (head 28c3d2da674aa9cd470995ce6bd39c4434e026fe)
author | John Bailey <rekkanoryo@rekkanoryo.org> |
---|---|
date | Sat, 05 Mar 2011 17:18:10 +0000 |
parents | a8cc50c2279f |
children |
rev | line source |
---|---|
29538 | 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 = | |
30872 | 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); | |
29538 | 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; | |
31534
a8cc50c2279f
Remove trailing whitespace
Richard Laager <rlaager@wiktel.com>
parents:
30872
diff
changeset
|
123 default: |
29538 | 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)); | |
31534
a8cc50c2279f
Remove trailing whitespace
Richard Laager <rlaager@wiktel.com>
parents:
30872
diff
changeset
|
136 |
29538 | 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; | |
31534
a8cc50c2279f
Remove trailing whitespace
Richard Laager <rlaager@wiktel.com>
parents:
30872
diff
changeset
|
158 default: |
29538 | 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; | |
31534
a8cc50c2279f
Remove trailing whitespace
Richard Laager <rlaager@wiktel.com>
parents:
30872
diff
changeset
|
169 |
29538 | 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); | |
30872 | 310 g_free(param); |
29538 | 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 |