Ignore:
Timestamp:
Jan 26, 2010 3:29:23 PM (14 years ago)
Author:
nanang
Message:

Ticket #1028:

  • Added new API pjmedia_codec_mgr_set_default_param() to set/update default codec parameter and implemented pjsua_codec_set_param() based on it.
  • Added mutex in codec manager to protect states manipulations.
  • Modified API pjmedia_codec_mgr_init() to add pool factory param.
  • Added new API pjmedia_codec_mgr_destroy().
  • Updated passthrough codec AMR to regard peer's mode-set setting.
  • Fixed VAS audio device to apply AMR encoding bitrate setting.
  • Fixed IPP codec codec_open() to update AMR bitrate info (for stream) when AMR encoding bitrate is not using the default, e.g: requested by peer via format param 'mode-set' in SDP.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia/codec.c

    r2394 r3074  
    2323#include <pj/assert.h> 
    2424#include <pj/log.h> 
    25 #include <pj/pool.h> 
    2625#include <pj/string.h> 
    2726 
     
    2928 
    3029 
     30 
     31/* Definition of default codecs parameters */ 
     32struct pjmedia_codec_default_param 
     33{ 
     34    pj_pool_t           *pool; 
     35    pjmedia_codec_param *param; 
     36}; 
    3137 
    3238 
     
    3844 * Initialize codec manager. 
    3945 */ 
    40 PJ_DEF(pj_status_t) pjmedia_codec_mgr_init (pjmedia_codec_mgr *mgr) 
    41 { 
    42     PJ_ASSERT_RETURN(mgr, PJ_EINVAL); 
    43  
     46PJ_DEF(pj_status_t) pjmedia_codec_mgr_init (pjmedia_codec_mgr *mgr, 
     47                                            pj_pool_factory *pf) 
     48{ 
     49    pj_status_t status; 
     50 
     51    PJ_ASSERT_RETURN(mgr && pf, PJ_EINVAL); 
     52 
     53    /* Init codec manager */ 
     54    pj_bzero(mgr, sizeof(pjmedia_codec_mgr)); 
     55    mgr->pf = pf; 
    4456    pj_list_init (&mgr->factory_list); 
    4557    mgr->codec_cnt = 0; 
     58 
     59    /* Create pool */ 
     60    mgr->pool = pj_pool_create(mgr->pf, "codec-mgr", 256, 256, NULL); 
     61 
     62    /* Create mutex */ 
     63    status = pj_mutex_create_recursive(mgr->pool, "codec-mgr", &mgr->mutex); 
     64    if (status != PJ_SUCCESS) 
     65        return status; 
     66 
     67    return PJ_SUCCESS; 
     68} 
     69 
     70/* 
     71 * Initialize codec manager. 
     72 */ 
     73PJ_DEF(pj_status_t) pjmedia_codec_mgr_destroy (pjmedia_codec_mgr *mgr) 
     74{ 
     75    unsigned i; 
     76 
     77    PJ_ASSERT_RETURN(mgr, PJ_EINVAL); 
     78 
     79    /* Cleanup all pools of all codec default params */ 
     80    for (i=0; i<mgr->codec_cnt; ++i) { 
     81        if (mgr->codec_desc[i].param) { 
     82            pj_assert(mgr->codec_desc[i].param->pool); 
     83            pj_pool_release(mgr->codec_desc[i].param->pool); 
     84        } 
     85    } 
     86 
     87    /* Destroy mutex */ 
     88    pj_mutex_destroy(mgr->mutex); 
     89 
     90    /* Release pool */ 
     91    pj_pool_release(mgr->pool); 
     92 
     93    /* Just for safety, set codec manager states to zero */ 
     94    pj_bzero(mgr, sizeof(pjmedia_codec_mgr)); 
    4695 
    4796    return PJ_SUCCESS; 
     
    66115    if (status != PJ_SUCCESS) 
    67116        return status; 
    68      
     117 
     118    pj_mutex_lock(mgr->mutex); 
    69119 
    70120    /* Check codec count */ 
    71     if (count + mgr->codec_cnt > PJ_ARRAY_SIZE(mgr->codec_desc)) 
     121    if (count + mgr->codec_cnt > PJ_ARRAY_SIZE(mgr->codec_desc)) { 
     122        pj_mutex_unlock(mgr->mutex); 
    72123        return PJ_ETOOMANY; 
     124    } 
    73125 
    74126 
     
    93145    pj_list_push_back(&mgr->factory_list, factory); 
    94146 
     147    pj_mutex_unlock(mgr->mutex); 
    95148 
    96149    return PJ_SUCCESS; 
     
    108161    PJ_ASSERT_RETURN(mgr && factory, PJ_EINVAL); 
    109162 
     163    pj_mutex_lock(mgr->mutex); 
     164 
    110165    /* Factory must be registered. */ 
    111     PJ_ASSERT_RETURN(pj_list_find_node(&mgr->factory_list, factory)==factory, 
    112                      PJ_ENOTFOUND); 
     166    if (pj_list_find_node(&mgr->factory_list, factory) != factory) { 
     167        pj_mutex_unlock(mgr->mutex); 
     168        return PJ_ENOTFOUND; 
     169    } 
    113170 
    114171    /* Erase factory from the factory list */ 
     
    122179 
    123180        if (mgr->codec_desc[i].factory == factory) { 
    124  
     181            /* Release pool of codec default param */ 
     182            if (mgr->codec_desc[i].param) { 
     183                pj_assert(mgr->codec_desc[i].param->pool); 
     184                pj_pool_release(mgr->codec_desc[i].param->pool); 
     185            } 
     186 
     187            /* Remove the codec from array of codec descriptions */ 
    125188            pj_array_erase(mgr->codec_desc, sizeof(mgr->codec_desc[0]),  
    126189                           mgr->codec_cnt, i); 
     
    132195    } 
    133196 
     197    pj_mutex_unlock(mgr->mutex); 
    134198 
    135199    return PJ_SUCCESS; 
     
    148212 
    149213    PJ_ASSERT_RETURN(mgr && count && codecs, PJ_EINVAL); 
     214 
     215    pj_mutex_lock(mgr->mutex); 
    150216 
    151217    if (*count > mgr->codec_cnt) 
     
    163229    } 
    164230 
     231    pj_mutex_unlock(mgr->mutex); 
     232 
    165233    return PJ_SUCCESS; 
    166234} 
     
    178246    PJ_ASSERT_RETURN(mgr && p_info && pt>=0 && pt < 96, PJ_EINVAL); 
    179247 
     248    pj_mutex_lock(mgr->mutex); 
     249 
    180250    for (i=0; i<mgr->codec_cnt; ++i) { 
    181251        if (mgr->codec_desc[i].info.pt == pt) { 
    182252            *p_info = &mgr->codec_desc[i].info; 
     253 
     254            pj_mutex_unlock(mgr->mutex); 
    183255            return PJ_SUCCESS; 
    184256        } 
    185257    } 
     258 
     259    pj_mutex_unlock(mgr->mutex); 
    186260 
    187261    return PJMEDIA_CODEC_EUNSUP; 
     
    231305    PJ_ASSERT_RETURN(mgr && codec_id && count && *count, PJ_EINVAL); 
    232306 
     307    pj_mutex_lock(mgr->mutex); 
     308 
    233309    for (i=0; i<mgr->codec_cnt; ++i) { 
    234310 
     
    250326 
    251327    } 
     328 
     329    pj_mutex_unlock(mgr->mutex); 
    252330 
    253331    *count = found; 
     
    313391 
    314392    PJ_ASSERT_RETURN(mgr && codec_id, PJ_EINVAL); 
     393 
     394    pj_mutex_lock(mgr->mutex); 
    315395 
    316396    /* Update the priorities of affected codecs */ 
     
    326406    } 
    327407 
    328     if (!found) 
     408    if (!found) { 
     409        pj_mutex_unlock(mgr->mutex); 
    329410        return PJ_ENOTFOUND; 
     411    } 
    330412 
    331413    /* Re-sort codecs */ 
    332414    sort_codecs(mgr); 
    333   
     415 
     416    pj_mutex_unlock(mgr->mutex); 
    334417 
    335418    return PJ_SUCCESS; 
     
    351434    *p_codec = NULL; 
    352435 
     436    pj_mutex_lock(mgr->mutex); 
     437 
    353438    factory = mgr->factory_list.next; 
    354439    while (factory != &mgr->factory_list) { 
     
    357442 
    358443            status = (*factory->op->alloc_codec)(factory, info, p_codec); 
    359             if (status == PJ_SUCCESS) 
     444            if (status == PJ_SUCCESS) { 
     445                pj_mutex_unlock(mgr->mutex); 
    360446                return PJ_SUCCESS; 
     447            } 
    361448 
    362449        } 
     
    365452    } 
    366453 
     454    pj_mutex_unlock(mgr->mutex); 
    367455 
    368456    return PJMEDIA_CODEC_EUNSUP; 
     
    379467    pjmedia_codec_factory *factory; 
    380468    pj_status_t status; 
     469    pjmedia_codec_id codec_id; 
     470    struct pjmedia_codec_desc *codec_desc = NULL; 
     471    unsigned i; 
    381472 
    382473    PJ_ASSERT_RETURN(mgr && info && param, PJ_EINVAL); 
    383474 
     475    if (!pjmedia_codec_info_to_id(info, (char*)&codec_id, sizeof(codec_id))) 
     476        return PJ_EINVAL; 
     477 
     478    pj_mutex_lock(mgr->mutex); 
     479 
     480    /* First, lookup default param in codec desc */ 
     481    for (i=0; i < mgr->codec_cnt; ++i) { 
     482        if (pj_ansi_stricmp(codec_id, mgr->codec_desc[i].id) == 0) { 
     483            codec_desc = &mgr->codec_desc[i]; 
     484            break; 
     485        } 
     486    } 
     487 
     488    /* If we found the codec and its default param is set, return it */ 
     489    if (codec_desc && codec_desc->param) { 
     490        pj_assert(codec_desc->param->param); 
     491        pj_memcpy(param, codec_desc->param->param,  
     492                  sizeof(pjmedia_codec_param)); 
     493 
     494        pj_mutex_unlock(mgr->mutex); 
     495        return PJ_SUCCESS; 
     496    } 
     497 
     498    /* Otherwise query the default param from codec factory */ 
    384499    factory = mgr->factory_list.next; 
    385500    while (factory != &mgr->factory_list) { 
     
    393508                    param->info.max_bps = param->info.avg_bps; 
    394509 
     510                pj_mutex_unlock(mgr->mutex); 
    395511                return PJ_SUCCESS; 
    396512            } 
     
    401517    } 
    402518 
     519    pj_mutex_unlock(mgr->mutex); 
     520 
    403521 
    404522    return PJMEDIA_CODEC_EUNSUP; 
     523} 
     524 
     525 
     526/* 
     527 * Set default codec parameter. 
     528 */ 
     529PJ_DEF(pj_status_t) pjmedia_codec_mgr_set_default_param(  
     530                                            pjmedia_codec_mgr *mgr, 
     531                                            const pjmedia_codec_info *info, 
     532                                            const pjmedia_codec_param *param ) 
     533{ 
     534    unsigned i; 
     535    pjmedia_codec_id codec_id; 
     536    pj_pool_t *pool; 
     537    struct pjmedia_codec_desc *codec_desc = NULL; 
     538    pjmedia_codec_default_param *p; 
     539 
     540    PJ_ASSERT_RETURN(mgr && info, PJ_EINVAL); 
     541 
     542    if (!pjmedia_codec_info_to_id(info, (char*)&codec_id, sizeof(codec_id))) 
     543        return PJ_EINVAL; 
     544 
     545    pj_mutex_lock(mgr->mutex); 
     546 
     547    /* Lookup codec desc */ 
     548    for (i=0; i < mgr->codec_cnt; ++i) { 
     549        if (pj_ansi_stricmp(codec_id, mgr->codec_desc[i].id) == 0) { 
     550            codec_desc = &mgr->codec_desc[i]; 
     551            break; 
     552        } 
     553    } 
     554 
     555    /* Codec not found */ 
     556    if (!codec_desc) { 
     557        pj_mutex_unlock(mgr->mutex); 
     558        return PJMEDIA_CODEC_EUNSUP; 
     559    } 
     560 
     561    /* If codec param is previously set, release codec param pool */ 
     562    if (codec_desc->param) { 
     563        pj_assert(codec_desc->param->pool); 
     564        pj_pool_release(codec_desc->param->pool); 
     565        codec_desc->param = NULL; 
     566    } 
     567 
     568    /* When param is set to NULL, i.e: setting default codec param to library 
     569     * default setting, just return PJ_SUCCESS. 
     570     */ 
     571    if (NULL == param) { 
     572        pj_mutex_unlock(mgr->mutex); 
     573        return PJ_SUCCESS; 
     574    } 
     575 
     576    /* Instantiate and initialize codec param */ 
     577    pool = pj_pool_create(mgr->pf, (char*)codec_id, 256, 256, NULL); 
     578    codec_desc->param = PJ_POOL_ZALLOC_T(pool, pjmedia_codec_default_param); 
     579    p = codec_desc->param; 
     580    p->pool = pool; 
     581    p->param = PJ_POOL_ZALLOC_T(pool, pjmedia_codec_param); 
     582 
     583    /* Update codec param */ 
     584    pj_memcpy(p->param, param, sizeof(pjmedia_codec_param)); 
     585    for (i = 0; i < param->setting.dec_fmtp.cnt; ++i) { 
     586        pj_strdup(pool, &p->param->setting.dec_fmtp.param[i].name,  
     587                  &param->setting.dec_fmtp.param[i].name); 
     588        pj_strdup(pool, &p->param->setting.dec_fmtp.param[i].val,  
     589                  &param->setting.dec_fmtp.param[i].val); 
     590    } 
     591    for (i = 0; i < param->setting.dec_fmtp.cnt; ++i) { 
     592        pj_strdup(pool, &p->param->setting.dec_fmtp.param[i].name,  
     593                  &param->setting.dec_fmtp.param[i].name); 
     594        pj_strdup(pool, &p->param->setting.dec_fmtp.param[i].val,  
     595                  &param->setting.dec_fmtp.param[i].val); 
     596    } 
     597 
     598    pj_mutex_unlock(mgr->mutex); 
     599 
     600    return PJ_SUCCESS; 
    405601} 
    406602 
Note: See TracChangeset for help on using the changeset viewer.