Mercurial > pidgin
comparison libpurple/media/codec.c @ 29392:f549ad844d54
propagate from branch 'im.pidgin.pidgin.next.minor' (head 42544ec892337510146c931806a95dbf69c2fe30)
to branch 'im.pidgin.pidgin' (head 32a27a2c6eebcccdecd7d7cd420b3789c69cbb09)
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Thu, 18 Feb 2010 09:22:01 +0000 |
parents | e18c1d347e37 |
children | 1feb2baeac2d |
comparison
equal
deleted
inserted
replaced
29391:4c266d9c17eb | 29392:f549ad844d54 |
---|---|
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 = | |
86 g_list_delete_link(priv->optional_params, | |
87 priv->optional_params)) { | |
88 g_free(priv->optional_params->data); | |
89 } | |
90 } | |
91 | |
92 static void | |
93 purple_media_codec_set_property (GObject *object, guint prop_id, | |
94 const GValue *value, GParamSpec *pspec) | |
95 { | |
96 PurpleMediaCodecPrivate *priv; | |
97 g_return_if_fail(PURPLE_IS_MEDIA_CODEC(object)); | |
98 | |
99 priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(object); | |
100 | |
101 switch (prop_id) { | |
102 case PROP_ID: | |
103 priv->id = g_value_get_uint(value); | |
104 break; | |
105 case PROP_ENCODING_NAME: | |
106 g_free(priv->encoding_name); | |
107 priv->encoding_name = g_value_dup_string(value); | |
108 break; | |
109 case PROP_MEDIA_TYPE: | |
110 priv->media_type = g_value_get_flags(value); | |
111 break; | |
112 case PROP_CLOCK_RATE: | |
113 priv->clock_rate = g_value_get_uint(value); | |
114 break; | |
115 case PROP_CHANNELS: | |
116 priv->channels = g_value_get_uint(value); | |
117 break; | |
118 case PROP_OPTIONAL_PARAMS: | |
119 priv->optional_params = g_value_get_pointer(value); | |
120 break; | |
121 default: | |
122 G_OBJECT_WARN_INVALID_PROPERTY_ID( | |
123 object, prop_id, pspec); | |
124 break; | |
125 } | |
126 } | |
127 | |
128 static void | |
129 purple_media_codec_get_property (GObject *object, guint prop_id, | |
130 GValue *value, GParamSpec *pspec) | |
131 { | |
132 PurpleMediaCodecPrivate *priv; | |
133 g_return_if_fail(PURPLE_IS_MEDIA_CODEC(object)); | |
134 | |
135 priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(object); | |
136 | |
137 switch (prop_id) { | |
138 case PROP_ID: | |
139 g_value_set_uint(value, priv->id); | |
140 break; | |
141 case PROP_ENCODING_NAME: | |
142 g_value_set_string(value, priv->encoding_name); | |
143 break; | |
144 case PROP_MEDIA_TYPE: | |
145 g_value_set_flags(value, priv->media_type); | |
146 break; | |
147 case PROP_CLOCK_RATE: | |
148 g_value_set_uint(value, priv->clock_rate); | |
149 break; | |
150 case PROP_CHANNELS: | |
151 g_value_set_uint(value, priv->channels); | |
152 break; | |
153 case PROP_OPTIONAL_PARAMS: | |
154 g_value_set_pointer(value, priv->optional_params); | |
155 break; | |
156 default: | |
157 G_OBJECT_WARN_INVALID_PROPERTY_ID( | |
158 object, prop_id, pspec); | |
159 break; | |
160 } | |
161 } | |
162 | |
163 static void | |
164 purple_media_codec_class_init(PurpleMediaCodecClass *klass) | |
165 { | |
166 GObjectClass *gobject_class = (GObjectClass*)klass; | |
167 | |
168 gobject_class->finalize = purple_media_codec_finalize; | |
169 gobject_class->set_property = purple_media_codec_set_property; | |
170 gobject_class->get_property = purple_media_codec_get_property; | |
171 | |
172 g_object_class_install_property(gobject_class, PROP_ID, | |
173 g_param_spec_uint("id", | |
174 "ID", | |
175 "The numeric identifier of the codec.", | |
176 0, G_MAXUINT, 0, | |
177 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); | |
178 | |
179 g_object_class_install_property(gobject_class, PROP_ENCODING_NAME, | |
180 g_param_spec_string("encoding-name", | |
181 "Encoding Name", | |
182 "The name of the codec.", | |
183 NULL, | |
184 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); | |
185 | |
186 g_object_class_install_property(gobject_class, PROP_MEDIA_TYPE, | |
187 g_param_spec_flags("media-type", | |
188 "Media Type", | |
189 "Whether this is an audio of video codec.", | |
190 PURPLE_TYPE_MEDIA_SESSION_TYPE, | |
191 PURPLE_MEDIA_NONE, | |
192 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); | |
193 | |
194 g_object_class_install_property(gobject_class, PROP_CLOCK_RATE, | |
195 g_param_spec_uint("clock-rate", | |
196 "Create Callback", | |
197 "The function called to create this element.", | |
198 0, G_MAXUINT, 0, | |
199 G_PARAM_READWRITE)); | |
200 | |
201 g_object_class_install_property(gobject_class, PROP_CHANNELS, | |
202 g_param_spec_uint("channels", | |
203 "Channels", | |
204 "The number of channels in this codec.", | |
205 0, G_MAXUINT, 0, | |
206 G_PARAM_READWRITE)); | |
207 g_object_class_install_property(gobject_class, PROP_OPTIONAL_PARAMS, | |
208 g_param_spec_pointer("optional-params", | |
209 "Optional Params", | |
210 "A list of optional parameters for the codec.", | |
211 G_PARAM_READWRITE)); | |
212 | |
213 g_type_class_add_private(klass, sizeof(PurpleMediaCodecPrivate)); | |
214 } | |
215 | |
216 PurpleMediaCodec * | |
217 purple_media_codec_new(int id, const char *encoding_name, | |
218 PurpleMediaSessionType media_type, guint clock_rate) | |
219 { | |
220 PurpleMediaCodec *codec = | |
221 g_object_new(PURPLE_TYPE_MEDIA_CODEC, | |
222 "id", id, | |
223 "encoding_name", encoding_name, | |
224 "media_type", media_type, | |
225 "clock-rate", clock_rate, NULL); | |
226 return codec; | |
227 } | |
228 | |
229 guint | |
230 purple_media_codec_get_id(PurpleMediaCodec *codec) | |
231 { | |
232 guint id; | |
233 g_return_val_if_fail(PURPLE_IS_MEDIA_CODEC(codec), 0); | |
234 g_object_get(codec, "id", &id, NULL); | |
235 return id; | |
236 } | |
237 | |
238 gchar * | |
239 purple_media_codec_get_encoding_name(PurpleMediaCodec *codec) | |
240 { | |
241 gchar *name; | |
242 g_return_val_if_fail(PURPLE_IS_MEDIA_CODEC(codec), NULL); | |
243 g_object_get(codec, "encoding-name", &name, NULL); | |
244 return name; | |
245 } | |
246 | |
247 guint | |
248 purple_media_codec_get_clock_rate(PurpleMediaCodec *codec) | |
249 { | |
250 guint clock_rate; | |
251 g_return_val_if_fail(PURPLE_IS_MEDIA_CODEC(codec), 0); | |
252 g_object_get(codec, "clock-rate", &clock_rate, NULL); | |
253 return clock_rate; | |
254 } | |
255 | |
256 guint | |
257 purple_media_codec_get_channels(PurpleMediaCodec *codec) | |
258 { | |
259 guint channels; | |
260 g_return_val_if_fail(PURPLE_IS_MEDIA_CODEC(codec), 0); | |
261 g_object_get(codec, "channels", &channels, NULL); | |
262 return channels; | |
263 } | |
264 | |
265 GList * | |
266 purple_media_codec_get_optional_parameters(PurpleMediaCodec *codec) | |
267 { | |
268 GList *optional_params; | |
269 g_return_val_if_fail(PURPLE_IS_MEDIA_CODEC(codec), NULL); | |
270 g_object_get(codec, "optional-params", &optional_params, NULL); | |
271 return optional_params; | |
272 } | |
273 | |
274 void | |
275 purple_media_codec_add_optional_parameter(PurpleMediaCodec *codec, | |
276 const gchar *name, const gchar *value) | |
277 { | |
278 PurpleMediaCodecPrivate *priv; | |
279 PurpleKeyValuePair *new_param; | |
280 | |
281 g_return_if_fail(codec != NULL); | |
282 g_return_if_fail(name != NULL && value != NULL); | |
283 | |
284 priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(codec); | |
285 | |
286 new_param = g_new0(PurpleKeyValuePair, 1); | |
287 new_param->key = g_strdup(name); | |
288 new_param->value = g_strdup(value); | |
289 priv->optional_params = g_list_append( | |
290 priv->optional_params, new_param); | |
291 } | |
292 | |
293 void | |
294 purple_media_codec_remove_optional_parameter(PurpleMediaCodec *codec, | |
295 PurpleKeyValuePair *param) | |
296 { | |
297 PurpleMediaCodecPrivate *priv; | |
298 | |
299 g_return_if_fail(codec != NULL && param != NULL); | |
300 | |
301 priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(codec); | |
302 | |
303 g_free(param->key); | |
304 g_free(param->value); | |
305 g_free(param); | |
306 | |
307 priv->optional_params = | |
308 g_list_remove(priv->optional_params, param); | |
309 } | |
310 | |
311 PurpleKeyValuePair * | |
312 purple_media_codec_get_optional_parameter(PurpleMediaCodec *codec, | |
313 const gchar *name, const gchar *value) | |
314 { | |
315 PurpleMediaCodecPrivate *priv; | |
316 GList *iter; | |
317 | |
318 g_return_val_if_fail(codec != NULL, NULL); | |
319 g_return_val_if_fail(name != NULL, NULL); | |
320 | |
321 priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(codec); | |
322 | |
323 for (iter = priv->optional_params; iter; iter = g_list_next(iter)) { | |
324 PurpleKeyValuePair *param = iter->data; | |
325 if (!g_ascii_strcasecmp(param->key, name) && | |
326 (value == NULL || | |
327 !g_ascii_strcasecmp(param->value, value))) | |
328 return param; | |
329 } | |
330 | |
331 return NULL; | |
332 } | |
333 | |
334 PurpleMediaCodec * | |
335 purple_media_codec_copy(PurpleMediaCodec *codec) | |
336 { | |
337 PurpleMediaCodecPrivate *priv; | |
338 PurpleMediaCodec *new_codec; | |
339 GList *iter; | |
340 | |
341 if (codec == NULL) | |
342 return NULL; | |
343 | |
344 priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(codec); | |
345 | |
346 new_codec = purple_media_codec_new(priv->id, priv->encoding_name, | |
347 priv->media_type, priv->clock_rate); | |
348 g_object_set(codec, "channels", priv->channels, NULL); | |
349 | |
350 for (iter = priv->optional_params; iter; iter = g_list_next(iter)) { | |
351 PurpleKeyValuePair *param = | |
352 (PurpleKeyValuePair*)iter->data; | |
353 purple_media_codec_add_optional_parameter(new_codec, | |
354 param->key, param->value); | |
355 } | |
356 | |
357 return new_codec; | |
358 } | |
359 | |
360 GList * | |
361 purple_media_codec_list_copy(GList *codecs) | |
362 { | |
363 GList *new_list = NULL; | |
364 | |
365 for (; codecs; codecs = g_list_next(codecs)) { | |
366 new_list = g_list_prepend(new_list, | |
367 purple_media_codec_copy(codecs->data)); | |
368 } | |
369 | |
370 new_list = g_list_reverse(new_list); | |
371 return new_list; | |
372 } | |
373 | |
374 void | |
375 purple_media_codec_list_free(GList *codecs) | |
376 { | |
377 for (; codecs; codecs = | |
378 g_list_delete_link(codecs, codecs)) { | |
379 g_object_unref(codecs->data); | |
380 } | |
381 } | |
382 | |
383 gchar * | |
384 purple_media_codec_to_string(const PurpleMediaCodec *codec) | |
385 { | |
386 PurpleMediaCodecPrivate *priv; | |
387 GString *string = NULL; | |
388 GList *item; | |
389 gchar *charstring; | |
390 const gchar *media_type_str = NULL; | |
391 | |
392 if (codec == NULL) | |
393 return g_strdup("(NULL)"); | |
394 | |
395 priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(codec); | |
396 | |
397 string = g_string_new(""); | |
398 | |
399 if (priv->media_type & PURPLE_MEDIA_AUDIO) | |
400 media_type_str = "audio"; | |
401 else if (priv->media_type & PURPLE_MEDIA_VIDEO) | |
402 media_type_str = "video"; | |
403 | |
404 g_string_printf(string, "%d: %s %s clock:%d channels:%d", priv->id, | |
405 media_type_str, priv->encoding_name, | |
406 priv->clock_rate, priv->channels); | |
407 | |
408 for (item = priv->optional_params; item; item = g_list_next (item)) { | |
409 PurpleKeyValuePair *param = item->data; | |
410 g_string_append_printf (string, " %s=%s", | |
411 param->key, (gchar *)param->value); | |
412 } | |
413 | |
414 charstring = string->str; | |
415 g_string_free (string, FALSE); | |
416 | |
417 return charstring; | |
418 } | |
419 |