~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.1.0/pjmedia/src/pjmedia/vid_codec.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (1.1.11)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: package-import@ubuntu.com-20140128182336-3xenud1kbnwmf3mz
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: vid_codec.c 4008 2012-04-03 04:03:19Z nanang $ */
 
2
/* 
 
3
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 
4
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 
19
 */
 
20
#include <pjmedia/vid_codec.h>
 
21
#include <pjmedia/errno.h>
 
22
#include <pj/array.h>
 
23
#include <pj/assert.h>
 
24
#include <pj/log.h>
 
25
#include <pj/string.h>
 
26
 
 
27
 
 
28
#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
 
29
 
 
30
 
 
31
#define THIS_FILE   "vid_codec.c"
 
32
 
 
33
static pjmedia_vid_codec_mgr *def_vid_codec_mgr;
 
34
 
 
35
 
 
36
/* Definition of default codecs parameters */
 
37
typedef struct pjmedia_vid_codec_default_param
 
38
{
 
39
    pj_pool_t                   *pool;
 
40
    pjmedia_vid_codec_param     *param;
 
41
} pjmedia_vid_codec_default_param;
 
42
 
 
43
 
 
44
/*
 
45
 * Codec manager maintains array of these structs for each supported
 
46
 * codec.
 
47
 */
 
48
typedef struct pjmedia_vid_codec_desc
 
49
{
 
50
    pjmedia_vid_codec_info           info;      /**< Codec info.            */
 
51
    pjmedia_codec_id                 id;        /**< Fully qualified name   */
 
52
    pjmedia_codec_priority           prio;      /**< Priority.              */
 
53
    pjmedia_vid_codec_factory       *factory;   /**< The factory.           */
 
54
    pjmedia_vid_codec_default_param *def_param; /**< Default codecs 
 
55
                                                     parameters.            */
 
56
} pjmedia_vid_codec_desc;
 
57
 
 
58
 
 
59
/* The declaration of video codec manager */
 
60
struct pjmedia_vid_codec_mgr
 
61
{
 
62
    /** Pool factory instance. */
 
63
    pj_pool_factory             *pf;
 
64
 
 
65
    /** Codec manager mutex. */
 
66
    pj_mutex_t                  *mutex;
 
67
 
 
68
    /** List of codec factories registered to codec manager. */
 
69
    pjmedia_vid_codec_factory    factory_list;
 
70
 
 
71
    /** Number of supported codecs. */
 
72
    unsigned                     codec_cnt;
 
73
 
 
74
    /** Array of codec descriptor. */
 
75
    pjmedia_vid_codec_desc       codec_desc[PJMEDIA_CODEC_MGR_MAX_CODECS];
 
76
 
 
77
};
 
78
 
 
79
 
 
80
 
 
81
/* Sort codecs in codec manager based on priorities */
 
82
static void sort_codecs(pjmedia_vid_codec_mgr *mgr);
 
83
 
 
84
 
 
85
/*
 
86
 * Duplicate video codec parameter.
 
87
 */
 
88
PJ_DEF(pjmedia_vid_codec_param*) pjmedia_vid_codec_param_clone(
 
89
                                        pj_pool_t *pool, 
 
90
                                        const pjmedia_vid_codec_param *src)
 
91
{
 
92
    pjmedia_vid_codec_param *p;
 
93
    unsigned i;
 
94
 
 
95
    PJ_ASSERT_RETURN(pool && src, NULL);
 
96
 
 
97
    p = PJ_POOL_ZALLOC_T(pool, pjmedia_vid_codec_param);
 
98
 
 
99
    /* Update codec param */
 
100
    pj_memcpy(p, src, sizeof(pjmedia_vid_codec_param));
 
101
    for (i = 0; i < src->dec_fmtp.cnt; ++i) {
 
102
        pj_strdup(pool, &p->dec_fmtp.param[i].name, 
 
103
                  &src->dec_fmtp.param[i].name);
 
104
        pj_strdup(pool, &p->dec_fmtp.param[i].val, 
 
105
                  &src->dec_fmtp.param[i].val);
 
106
    }
 
107
    for (i = 0; i < src->enc_fmtp.cnt; ++i) {
 
108
        pj_strdup(pool, &p->enc_fmtp.param[i].name, 
 
109
                  &src->enc_fmtp.param[i].name);
 
110
        pj_strdup(pool, &p->enc_fmtp.param[i].val, 
 
111
                  &src->enc_fmtp.param[i].val);
 
112
    }
 
113
 
 
114
    return p;
 
115
}
 
116
 
 
117
/*
 
118
 * Initialize codec manager.
 
119
 */
 
120
PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_create(
 
121
                                            pj_pool_t *pool,
 
122
                                            pjmedia_vid_codec_mgr **p_mgr)
 
123
{
 
124
    pjmedia_vid_codec_mgr *mgr;
 
125
    pj_status_t status;
 
126
 
 
127
    PJ_ASSERT_RETURN(pool, PJ_EINVAL);
 
128
 
 
129
    mgr = PJ_POOL_ZALLOC_T(pool, pjmedia_vid_codec_mgr);
 
130
    mgr->pf = pool->factory;
 
131
    pj_list_init (&mgr->factory_list);
 
132
    mgr->codec_cnt = 0;
 
133
 
 
134
    /* Create mutex */
 
135
    status = pj_mutex_create_recursive(pool, "vid-codec-mgr", &mgr->mutex);
 
136
    if (status != PJ_SUCCESS)
 
137
        return status;
 
138
 
 
139
    if (!def_vid_codec_mgr)
 
140
        def_vid_codec_mgr = mgr;
 
141
 
 
142
    if (p_mgr)
 
143
        *p_mgr = mgr;
 
144
 
 
145
    return PJ_SUCCESS;
 
146
}
 
147
 
 
148
/*
 
149
 * Initialize codec manager.
 
150
 */
 
151
PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_destroy (pjmedia_vid_codec_mgr *mgr)
 
152
{
 
153
    if (!mgr) mgr = def_vid_codec_mgr;
 
154
    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
 
155
 
 
156
    /* Destroy mutex */
 
157
    if (mgr->mutex)
 
158
        pj_mutex_destroy(mgr->mutex);
 
159
 
 
160
    /* Just for safety, set codec manager states to zero */
 
161
    pj_bzero(mgr, sizeof(pjmedia_vid_codec_mgr));
 
162
 
 
163
    if (mgr == def_vid_codec_mgr)
 
164
        def_vid_codec_mgr = NULL;
 
165
 
 
166
    return PJ_SUCCESS;
 
167
}
 
168
 
 
169
 
 
170
PJ_DEF(pjmedia_vid_codec_mgr*) pjmedia_vid_codec_mgr_instance(void)
 
171
{
 
172
    //pj_assert(def_vid_codec_mgr);
 
173
    return def_vid_codec_mgr;
 
174
}
 
175
 
 
176
PJ_DEF(void) pjmedia_vid_codec_mgr_set_instance(pjmedia_vid_codec_mgr* mgr)
 
177
{
 
178
    def_vid_codec_mgr = mgr;
 
179
}
 
180
 
 
181
 
 
182
/*
 
183
 * Register a codec factory.
 
184
 */
 
185
PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_register_factory(
 
186
                                    pjmedia_vid_codec_mgr *mgr,
 
187
                                    pjmedia_vid_codec_factory *factory)
 
188
{
 
189
    pjmedia_vid_codec_info info[PJMEDIA_CODEC_MGR_MAX_CODECS];
 
190
    unsigned i, count;
 
191
    pj_status_t status;
 
192
 
 
193
    PJ_ASSERT_RETURN(factory, PJ_EINVAL);
 
194
 
 
195
    if (!mgr) mgr = def_vid_codec_mgr;
 
196
    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
 
197
 
 
198
    /* Enum codecs */
 
199
    count = PJ_ARRAY_SIZE(info);
 
200
    status = factory->op->enum_info(factory, &count, info);
 
201
    if (status != PJ_SUCCESS)
 
202
        return status;
 
203
 
 
204
    pj_mutex_lock(mgr->mutex);
 
205
 
 
206
    /* Check codec count */
 
207
    if (count + mgr->codec_cnt > PJ_ARRAY_SIZE(mgr->codec_desc)) {
 
208
        pj_mutex_unlock(mgr->mutex);
 
209
        return PJ_ETOOMANY;
 
210
    }
 
211
 
 
212
 
 
213
    /* Save the codecs */
 
214
    for (i=0; i<count; ++i) {
 
215
        pj_memcpy( &mgr->codec_desc[mgr->codec_cnt+i],
 
216
                   &info[i], sizeof(pjmedia_vid_codec_info));
 
217
        mgr->codec_desc[mgr->codec_cnt+i].prio = PJMEDIA_CODEC_PRIO_NORMAL;
 
218
        mgr->codec_desc[mgr->codec_cnt+i].factory = factory;
 
219
        pjmedia_vid_codec_info_to_id( &info[i],
 
220
                                  mgr->codec_desc[mgr->codec_cnt+i].id,
 
221
                                  sizeof(pjmedia_codec_id));
 
222
    }
 
223
 
 
224
    /* Update count */
 
225
    mgr->codec_cnt += count;
 
226
 
 
227
    /* Re-sort codec based on priorities */
 
228
    sort_codecs(mgr);
 
229
 
 
230
    /* Add factory to the list */
 
231
    pj_list_push_back(&mgr->factory_list, factory);
 
232
 
 
233
    pj_mutex_unlock(mgr->mutex);
 
234
 
 
235
    return PJ_SUCCESS;
 
236
}
 
237
 
 
238
 
 
239
/*
 
240
 * Unregister a codec factory.
 
241
 */
 
242
PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_unregister_factory(
 
243
                                pjmedia_vid_codec_mgr *mgr, 
 
244
                                pjmedia_vid_codec_factory *factory)
 
245
{
 
246
    unsigned i;
 
247
    PJ_ASSERT_RETURN(factory, PJ_EINVAL);
 
248
 
 
249
    if (!mgr) mgr = def_vid_codec_mgr;
 
250
    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
 
251
 
 
252
    pj_mutex_lock(mgr->mutex);
 
253
 
 
254
    /* Factory must be registered. */
 
255
    if (pj_list_find_node(&mgr->factory_list, factory) != factory) {
 
256
        pj_mutex_unlock(mgr->mutex);
 
257
        return PJ_ENOTFOUND;
 
258
    }
 
259
 
 
260
    /* Erase factory from the factory list */
 
261
    pj_list_erase(factory);
 
262
 
 
263
 
 
264
    /* Remove all supported codecs from the codec manager that were created 
 
265
     * by the specified factory.
 
266
     */
 
267
    for (i=0; i<mgr->codec_cnt; ) {
 
268
 
 
269
        if (mgr->codec_desc[i].factory == factory) {
 
270
            /* Remove the codec from array of codec descriptions */
 
271
            pj_array_erase(mgr->codec_desc, sizeof(mgr->codec_desc[0]), 
 
272
                           mgr->codec_cnt, i);
 
273
            --mgr->codec_cnt;
 
274
 
 
275
        } else {
 
276
            ++i;
 
277
        }
 
278
    }
 
279
 
 
280
    pj_mutex_unlock(mgr->mutex);
 
281
 
 
282
    return PJ_SUCCESS;
 
283
}
 
284
 
 
285
 
 
286
/*
 
287
 * Enum all codecs.
 
288
 */
 
289
PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_enum_codecs(
 
290
                                pjmedia_vid_codec_mgr *mgr, 
 
291
                                unsigned *count, 
 
292
                                pjmedia_vid_codec_info codecs[],
 
293
                                unsigned *prio)
 
294
{
 
295
    unsigned i;
 
296
 
 
297
    PJ_ASSERT_RETURN(count && codecs, PJ_EINVAL);
 
298
 
 
299
    if (!mgr) mgr = def_vid_codec_mgr;
 
300
    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
 
301
 
 
302
    pj_mutex_lock(mgr->mutex);
 
303
 
 
304
    if (*count > mgr->codec_cnt)
 
305
        *count = mgr->codec_cnt;
 
306
    
 
307
    for (i=0; i<*count; ++i) {
 
308
        pj_memcpy(&codecs[i], 
 
309
                  &mgr->codec_desc[i].info, 
 
310
                  sizeof(pjmedia_vid_codec_info));
 
311
    }
 
312
 
 
313
    if (prio) {
 
314
        for (i=0; i < *count; ++i)
 
315
            prio[i] = mgr->codec_desc[i].prio;
 
316
    }
 
317
 
 
318
    pj_mutex_unlock(mgr->mutex);
 
319
 
 
320
    return PJ_SUCCESS;
 
321
}
 
322
 
 
323
 
 
324
/*
 
325
 * Get codec info for the specified payload type.
 
326
 */
 
327
PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_get_codec_info(
 
328
                                    pjmedia_vid_codec_mgr *mgr,
 
329
                                    unsigned pt,
 
330
                                    const pjmedia_vid_codec_info **p_info)
 
331
{
 
332
    unsigned i;
 
333
 
 
334
    PJ_ASSERT_RETURN(p_info, PJ_EINVAL);
 
335
 
 
336
    if (!mgr) mgr = def_vid_codec_mgr;
 
337
    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
 
338
 
 
339
    pj_mutex_lock(mgr->mutex);
 
340
 
 
341
    for (i=0; i<mgr->codec_cnt; ++i) {
 
342
        if (mgr->codec_desc[i].info.pt == pt) {
 
343
            *p_info = &mgr->codec_desc[i].info;
 
344
 
 
345
            pj_mutex_unlock(mgr->mutex);
 
346
            return PJ_SUCCESS;
 
347
        }
 
348
    }
 
349
 
 
350
    pj_mutex_unlock(mgr->mutex);
 
351
 
 
352
    return PJMEDIA_CODEC_EUNSUP;
 
353
}
 
354
 
 
355
 
 
356
PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_get_codec_info2(
 
357
                                    pjmedia_vid_codec_mgr *mgr,
 
358
                                    pjmedia_format_id fmt_id,
 
359
                                    const pjmedia_vid_codec_info **p_info)
 
360
{
 
361
    unsigned i;
 
362
 
 
363
    PJ_ASSERT_RETURN(p_info, PJ_EINVAL);
 
364
 
 
365
    if (!mgr) mgr = def_vid_codec_mgr;
 
366
    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
 
367
 
 
368
    pj_mutex_lock(mgr->mutex);
 
369
 
 
370
    for (i=0; i<mgr->codec_cnt; ++i) {
 
371
        if (mgr->codec_desc[i].info.fmt_id == fmt_id) {
 
372
            *p_info = &mgr->codec_desc[i].info;
 
373
 
 
374
            pj_mutex_unlock(mgr->mutex);
 
375
            return PJ_SUCCESS;
 
376
        }
 
377
    }
 
378
 
 
379
    pj_mutex_unlock(mgr->mutex);
 
380
 
 
381
    return PJMEDIA_CODEC_EUNSUP;
 
382
}
 
383
 
 
384
 
 
385
/*
 
386
 * Convert codec info struct into a unique codec identifier.
 
387
 * A codec identifier looks something like "H263/34".
 
388
 */
 
389
PJ_DEF(char*) pjmedia_vid_codec_info_to_id(
 
390
                                        const pjmedia_vid_codec_info *info,
 
391
                                        char *id, unsigned max_len )
 
392
{
 
393
    int len;
 
394
 
 
395
    PJ_ASSERT_RETURN(info && id && max_len, NULL);
 
396
 
 
397
    len = pj_ansi_snprintf(id, max_len, "%.*s/%u",
 
398
                           (int)info->encoding_name.slen,
 
399
                           info->encoding_name.ptr,
 
400
                           info->pt);
 
401
 
 
402
    if (len < 1 || len >= (int)max_len) {
 
403
        id[0] = '\0';
 
404
        return NULL;
 
405
    }
 
406
 
 
407
    return id;
 
408
}
 
409
 
 
410
 
 
411
/*
 
412
 * Find codecs by the unique codec identifier. This function will find
 
413
 * all codecs that match the codec identifier prefix. For example, if
 
414
 * "L16" is specified, then it will find "L16/8000/1", "L16/16000/1",
 
415
 * and so on, up to the maximum count specified in the argument.
 
416
 */
 
417
PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_find_codecs_by_id(
 
418
                                     pjmedia_vid_codec_mgr *mgr,
 
419
                                     const pj_str_t *codec_id,
 
420
                                     unsigned *count,
 
421
                                     const pjmedia_vid_codec_info *p_info[],
 
422
                                     unsigned prio[])
 
423
{
 
424
    unsigned i, found = 0;
 
425
 
 
426
    PJ_ASSERT_RETURN(codec_id && count && *count, PJ_EINVAL);
 
427
 
 
428
    if (!mgr) mgr = def_vid_codec_mgr;
 
429
    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
 
430
 
 
431
    pj_mutex_lock(mgr->mutex);
 
432
 
 
433
    for (i=0; i<mgr->codec_cnt; ++i) {
 
434
 
 
435
        if (codec_id->slen == 0 ||
 
436
            pj_strnicmp2(codec_id, mgr->codec_desc[i].id, 
 
437
                         codec_id->slen) == 0) 
 
438
        {
 
439
 
 
440
            if (p_info)
 
441
                p_info[found] = &mgr->codec_desc[i].info;
 
442
            if (prio)
 
443
                prio[found] = mgr->codec_desc[i].prio;
 
444
 
 
445
            ++found;
 
446
 
 
447
            if (found >= *count)
 
448
                break;
 
449
        }
 
450
 
 
451
    }
 
452
 
 
453
    pj_mutex_unlock(mgr->mutex);
 
454
 
 
455
    *count = found;
 
456
 
 
457
    return found ? PJ_SUCCESS : PJ_ENOTFOUND;
 
458
}
 
459
 
 
460
 
 
461
/* Swap two codecs positions in codec manager */
 
462
static void swap_codec(pjmedia_vid_codec_mgr *mgr, unsigned i, unsigned j)
 
463
{
 
464
    pjmedia_vid_codec_desc tmp;
 
465
 
 
466
    pj_memcpy(&tmp, &mgr->codec_desc[i], sizeof(pjmedia_vid_codec_desc));
 
467
 
 
468
    pj_memcpy(&mgr->codec_desc[i], &mgr->codec_desc[j], 
 
469
               sizeof(pjmedia_vid_codec_desc));
 
470
 
 
471
    pj_memcpy(&mgr->codec_desc[j], &tmp, sizeof(pjmedia_vid_codec_desc));
 
472
}
 
473
 
 
474
 
 
475
/* Sort codecs in codec manager based on priorities */
 
476
static void sort_codecs(pjmedia_vid_codec_mgr *mgr)
 
477
{
 
478
    unsigned i;
 
479
 
 
480
   /* Re-sort */
 
481
    for (i=0; i<mgr->codec_cnt; ++i) {
 
482
        unsigned j, max;
 
483
 
 
484
        for (max=i, j=i+1; j<mgr->codec_cnt; ++j) {
 
485
            if (mgr->codec_desc[j].prio > mgr->codec_desc[max].prio)
 
486
                max = j;
 
487
        }
 
488
 
 
489
        if (max != i)
 
490
            swap_codec(mgr, i, max);
 
491
    }
 
492
 
 
493
    /* Change PJMEDIA_CODEC_PRIO_HIGHEST codecs to NEXT_HIGHER */
 
494
    for (i=0; i<mgr->codec_cnt; ++i) {
 
495
        if (mgr->codec_desc[i].prio == PJMEDIA_CODEC_PRIO_HIGHEST)
 
496
            mgr->codec_desc[i].prio = PJMEDIA_CODEC_PRIO_NEXT_HIGHER;
 
497
        else
 
498
            break;
 
499
    }
 
500
}
 
501
 
 
502
 
 
503
/**
 
504
 * Set codec priority. The codec priority determines the order of
 
505
 * the codec in the SDP created by the endpoint. If more than one codecs
 
506
 * are found with the same codec_id prefix, then the function sets the
 
507
 * priorities of all those codecs.
 
508
 */
 
509
PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_set_codec_priority(
 
510
                                pjmedia_vid_codec_mgr *mgr, 
 
511
                                const pj_str_t *codec_id,
 
512
                                pj_uint8_t prio)
 
513
{
 
514
    unsigned i, found = 0;
 
515
 
 
516
    PJ_ASSERT_RETURN(codec_id, PJ_EINVAL);
 
517
 
 
518
    if (!mgr) mgr = def_vid_codec_mgr;
 
519
    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
 
520
 
 
521
    pj_mutex_lock(mgr->mutex);
 
522
 
 
523
    /* Update the priorities of affected codecs */
 
524
    for (i=0; i<mgr->codec_cnt; ++i) 
 
525
    {
 
526
        if (codec_id->slen == 0 ||
 
527
            pj_strnicmp2(codec_id, mgr->codec_desc[i].id, 
 
528
                         codec_id->slen) == 0) 
 
529
        {
 
530
            mgr->codec_desc[i].prio = (pjmedia_codec_priority) prio;
 
531
            ++found;
 
532
        }
 
533
    }
 
534
 
 
535
    if (!found) {
 
536
        pj_mutex_unlock(mgr->mutex);
 
537
        return PJ_ENOTFOUND;
 
538
    }
 
539
 
 
540
    /* Re-sort codecs */
 
541
    sort_codecs(mgr);
 
542
 
 
543
    pj_mutex_unlock(mgr->mutex);
 
544
 
 
545
    return PJ_SUCCESS;
 
546
}
 
547
 
 
548
 
 
549
/*
 
550
 * Allocate one codec.
 
551
 */
 
552
PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_alloc_codec(
 
553
                                        pjmedia_vid_codec_mgr *mgr, 
 
554
                                        const pjmedia_vid_codec_info *info,
 
555
                                        pjmedia_vid_codec **p_codec)
 
556
{
 
557
    pjmedia_vid_codec_factory *factory;
 
558
    pj_status_t status;
 
559
 
 
560
    PJ_ASSERT_RETURN(info && p_codec, PJ_EINVAL);
 
561
 
 
562
    if (!mgr) mgr = def_vid_codec_mgr;
 
563
    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
 
564
 
 
565
    *p_codec = NULL;
 
566
 
 
567
    pj_mutex_lock(mgr->mutex);
 
568
 
 
569
    factory = mgr->factory_list.next;
 
570
    while (factory != &mgr->factory_list) {
 
571
 
 
572
        if ( (*factory->op->test_alloc)(factory, info) == PJ_SUCCESS ) {
 
573
 
 
574
            status = (*factory->op->alloc_codec)(factory, info, p_codec);
 
575
            if (status == PJ_SUCCESS) {
 
576
                pj_mutex_unlock(mgr->mutex);
 
577
                return PJ_SUCCESS;
 
578
            }
 
579
 
 
580
        }
 
581
 
 
582
        factory = factory->next;
 
583
    }
 
584
 
 
585
    pj_mutex_unlock(mgr->mutex);
 
586
 
 
587
    return PJMEDIA_CODEC_EUNSUP;
 
588
}
 
589
 
 
590
 
 
591
/*
 
592
 * Get default codec parameter.
 
593
 */
 
594
PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_get_default_param(
 
595
                                        pjmedia_vid_codec_mgr *mgr,
 
596
                                        const pjmedia_vid_codec_info *info,
 
597
                                        pjmedia_vid_codec_param *param )
 
598
{
 
599
    pjmedia_vid_codec_factory *factory;
 
600
    pj_status_t status;
 
601
    pjmedia_codec_id codec_id;
 
602
    pjmedia_vid_codec_desc *codec_desc = NULL;
 
603
    unsigned i;
 
604
 
 
605
    PJ_ASSERT_RETURN(info && param, PJ_EINVAL);
 
606
 
 
607
    if (!mgr) mgr = def_vid_codec_mgr;
 
608
    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
 
609
 
 
610
    if (!pjmedia_vid_codec_info_to_id(info, (char*)&codec_id, 
 
611
                                      sizeof(codec_id)))
 
612
        return PJ_EINVAL;
 
613
 
 
614
    pj_mutex_lock(mgr->mutex);
 
615
 
 
616
    /* First, lookup default param in codec desc */
 
617
    for (i=0; i < mgr->codec_cnt; ++i) {
 
618
        if (pj_ansi_stricmp(codec_id, mgr->codec_desc[i].id) == 0) {
 
619
            codec_desc = &mgr->codec_desc[i];
 
620
            break;
 
621
        }
 
622
    }
 
623
 
 
624
    /* If we found the codec and its default param is set, return it */
 
625
    if (codec_desc && codec_desc->def_param) {
 
626
        pj_memcpy(param, codec_desc->def_param->param, 
 
627
                  sizeof(pjmedia_vid_codec_param));
 
628
 
 
629
        pj_mutex_unlock(mgr->mutex);
 
630
        return PJ_SUCCESS;
 
631
    }
 
632
 
 
633
    /* Otherwise query the default param from codec factory */
 
634
    factory = mgr->factory_list.next;
 
635
    while (factory != &mgr->factory_list) {
 
636
 
 
637
        if ( (*factory->op->test_alloc)(factory, info) == PJ_SUCCESS ) {
 
638
 
 
639
            status = (*factory->op->default_attr)(factory, info, param);
 
640
            if (status == PJ_SUCCESS) {
 
641
                /* Check for invalid max_bps. */
 
642
                //if (param->info.max_bps < param->info.avg_bps)
 
643
                //    param->info.max_bps = param->info.avg_bps;
 
644
 
 
645
                pj_mutex_unlock(mgr->mutex);
 
646
                return PJ_SUCCESS;
 
647
            }
 
648
 
 
649
        }
 
650
 
 
651
        factory = factory->next;
 
652
    }
 
653
 
 
654
    pj_mutex_unlock(mgr->mutex);
 
655
 
 
656
 
 
657
    return PJMEDIA_CODEC_EUNSUP;
 
658
}
 
659
 
 
660
 
 
661
/*
 
662
 * Set default codec parameter.
 
663
 */
 
664
PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_set_default_param( 
 
665
                                            pjmedia_vid_codec_mgr *mgr,
 
666
                                            const pjmedia_vid_codec_info *info,
 
667
                                            const pjmedia_vid_codec_param *param )
 
668
{
 
669
    unsigned i;
 
670
    pjmedia_codec_id codec_id;
 
671
    pjmedia_vid_codec_desc *codec_desc = NULL;
 
672
    pj_pool_t *pool, *old_pool = NULL;
 
673
    pjmedia_vid_codec_default_param *p;
 
674
 
 
675
    PJ_ASSERT_RETURN(info, PJ_EINVAL);
 
676
 
 
677
    if (!mgr) mgr = def_vid_codec_mgr;
 
678
    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
 
679
 
 
680
    if (!pjmedia_vid_codec_info_to_id(info, (char*)&codec_id, sizeof(codec_id)))
 
681
        return PJ_EINVAL;
 
682
 
 
683
    pj_mutex_lock(mgr->mutex);
 
684
 
 
685
    /* Lookup codec desc */
 
686
    for (i=0; i < mgr->codec_cnt; ++i) {
 
687
        if (pj_ansi_stricmp(codec_id, mgr->codec_desc[i].id) == 0) {
 
688
            codec_desc = &mgr->codec_desc[i];
 
689
            break;
 
690
        }
 
691
    }
 
692
 
 
693
    /* Codec not found */
 
694
    if (!codec_desc) {
 
695
        pj_mutex_unlock(mgr->mutex);
 
696
        return PJMEDIA_CODEC_EUNSUP;
 
697
    }
 
698
 
 
699
    /* If codec param is previously set */
 
700
    if (codec_desc->def_param) {
 
701
        pj_assert(codec_desc->def_param->pool);
 
702
        old_pool = codec_desc->def_param->pool;
 
703
        codec_desc->def_param = NULL;
 
704
    }
 
705
 
 
706
    /* When param is set to NULL, i.e: setting default codec param to library
 
707
     * default setting, just return PJ_SUCCESS.
 
708
     */
 
709
    if (NULL == param) {
 
710
        pj_mutex_unlock(mgr->mutex);
 
711
        if (old_pool)
 
712
            pj_pool_release(old_pool);
 
713
        return PJ_SUCCESS;
 
714
    }
 
715
 
 
716
    /* Create new default codec param instance */
 
717
    pool = pj_pool_create(mgr->pf, (char*)codec_id, 256, 256, NULL);
 
718
    codec_desc->def_param = PJ_POOL_ZALLOC_T(pool,
 
719
                                             pjmedia_vid_codec_default_param);
 
720
    p = codec_desc->def_param;
 
721
    p->pool = pool;
 
722
 
 
723
    /* Update codec default param */
 
724
    p->param = pjmedia_vid_codec_param_clone(pool, param);
 
725
    if (!p->param)
 
726
        return PJ_EINVAL;
 
727
 
 
728
    codec_desc->def_param = p;
 
729
 
 
730
    pj_mutex_unlock(mgr->mutex);
 
731
 
 
732
    /* Release old pool at the very end, as application tends to apply changes
 
733
     * to the existing/old codec param fetched using
 
734
     * pjmedia_vid_codec_mgr_get_default_param() which doesn't do deep clone.
 
735
     */
 
736
    if (old_pool)
 
737
        pj_pool_release(old_pool);
 
738
 
 
739
    return PJ_SUCCESS;
 
740
}
 
741
 
 
742
 
 
743
/*
 
744
 * Dealloc codec.
 
745
 */
 
746
PJ_DEF(pj_status_t)
 
747
pjmedia_vid_codec_mgr_dealloc_codec(pjmedia_vid_codec_mgr *mgr,
 
748
                                    pjmedia_vid_codec *codec)
 
749
{
 
750
    PJ_ASSERT_RETURN(codec, PJ_EINVAL);
 
751
 
 
752
    if (!mgr) mgr = def_vid_codec_mgr;
 
753
    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
 
754
 
 
755
    return (*codec->factory->op->dealloc_codec)(codec->factory, codec);
 
756
}
 
757
 
 
758
 
 
759
#endif /* PJMEDIA_HAS_VIDEO */