~liuxingcs/+junk/IM

« back to all changes in this revision

Viewing changes to libpurple/media/codec.c

  • Committer: liuxing
  • Date: 2013-04-25 10:41:36 UTC
  • Revision ID: liuxingcs@yeah.net-20130425104136-e5towjtz19wsz1w7
Init IM

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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, priv->optional_params)) {
 
87
                PurpleKeyValuePair *param = priv->optional_params->data;
 
88
                g_free(param->key);
 
89
                g_free(param->value);
 
90
                g_free(param);
 
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;
 
123
                default:
 
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));
 
136
 
 
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;
 
158
                default:
 
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;
 
169
 
 
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);
 
310
        g_free(param);
 
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