~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): Jonathan Riddell
  • Date: 2015-01-07 14:51:16 UTC
  • mfrom: (4.3.5 sid)
  • Revision ID: package-import@ubuntu.com-20150107145116-yxnafinf4lrdvrmx
Tags: 1.4.1-0.1ubuntu1
* Merge with Debian, remaining changes:
 - Drop soprano, nepomuk build-dep
* Drop ubuntu patches, now upstream

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 */