Changeset 3074


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.
Location:
pjproject/trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia-audiodev/symb_vas_dev.cpp

    r3025 r3074  
    492492        break; 
    493493         
     494    case EAMR_NB: 
     495        enc_fmt_if->SetBitRate(setting_.mode); 
     496        break; 
     497         
    494498    default: 
    495499        break; 
  • pjproject/trunk/pjmedia/src/pjmedia-codec/ipp_codecs.c

    r2851 r3074  
    11961196                  s->enc_mode, 
    11971197                  codec_data->info->params.modes.bitrate)); 
     1198 
     1199        /* Return back bitrate info to application */ 
     1200        attr->info.avg_bps = codec_data->info->params.modes.bitrate; 
    11981201    } 
    11991202#endif 
  • pjproject/trunk/pjmedia/src/pjmedia-codec/passthrough.c

    r2997 r3074  
    2525#include <pj/assert.h> 
    2626#include <pj/log.h> 
     27#include <pj/math.h> 
    2728#include <pj/pool.h> 
    2829#include <pj/string.h> 
     
    681682        amr_settings_t *s; 
    682683        pj_uint8_t octet_align = 0; 
    683         const pj_str_t STR_FMTP_OCTET_ALIGN = {"octet-align", 11}; 
     684        pj_int8_t enc_mode; 
     685 
     686        enc_mode = pjmedia_codec_amr_get_mode(attr->info.avg_bps); 
     687        pj_assert(enc_mode >= 0 && enc_mode <= 8); 
    684688 
    685689        /* Fetch octet-align setting. It should be fine to fetch only  
     
    688692         */ 
    689693        for (i = 0; i < attr->setting.dec_fmtp.cnt; ++i) { 
     694            const pj_str_t STR_FMTP_OCTET_ALIGN = {"octet-align", 11}; 
     695 
    690696            if (pj_stricmp(&attr->setting.dec_fmtp.param[i].name,  
    691697                           &STR_FMTP_OCTET_ALIGN) == 0) 
     
    697703        } 
    698704 
     705        for (i = 0; i < attr->setting.enc_fmtp.cnt; ++i) { 
     706            /* mode-set, encoding mode is chosen based on local default mode  
     707             * setting: 
     708             * - if local default mode is included in the mode-set, use it 
     709             * - otherwise, find the closest mode to local default mode; 
     710             *   if there are two closest modes, prefer to use the higher 
     711             *   one, e.g: local default mode is 4, the mode-set param 
     712             *   contains '2,3,5,6', then 5 will be chosen. 
     713             */ 
     714            const pj_str_t STR_FMTP_MODE_SET = {"mode-set", 8}; 
     715             
     716            if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name,  
     717                           &STR_FMTP_MODE_SET) == 0) 
     718            { 
     719                const char *p; 
     720                pj_size_t l; 
     721                pj_int8_t diff = 99; 
     722                 
     723                p = pj_strbuf(&attr->setting.enc_fmtp.param[i].val); 
     724                l = pj_strlen(&attr->setting.enc_fmtp.param[i].val); 
     725 
     726                while (l--) { 
     727                    if ((desc->pt==PJMEDIA_RTP_PT_AMR && *p>='0' && *p<='7') || 
     728                        (desc->pt==PJMEDIA_RTP_PT_AMRWB && *p>='0' && *p<='8')) 
     729                    { 
     730                        pj_int8_t tmp = (pj_int8_t)(*p - '0' - enc_mode); 
     731 
     732                        if (PJ_ABS(diff) > PJ_ABS(tmp) ||  
     733                            (PJ_ABS(diff) == PJ_ABS(tmp) && tmp > diff)) 
     734                        { 
     735                            diff = tmp; 
     736                            if (diff == 0) break; 
     737                        } 
     738                    } 
     739                    ++p; 
     740                } 
     741 
     742                if (diff == 99) 
     743                    return PJMEDIA_CODEC_EFAILED; 
     744 
     745                enc_mode = (pj_int8_t)(enc_mode + diff); 
     746 
     747                break; 
     748            } 
     749        } 
     750 
    699751        s = PJ_POOL_ZALLOC_T(pool, amr_settings_t); 
    700752        codec_data->codec_setting = s; 
    701753 
    702         s->enc_mode = pjmedia_codec_amr_get_mode(desc->def_bitrate); 
     754        s->enc_mode = enc_mode; 
    703755        if (s->enc_mode < 0) 
    704756            return PJMEDIA_CODEC_EINMODE; 
     
    716768                                              doesn't do sensitivity bits  
    717769                                              reordering */ 
     770 
     771        /* Return back bitrate info to application */ 
     772        attr->info.avg_bps = s->enc_setting.amr_nb? 
     773                                pjmedia_codec_amrnb_bitrates[s->enc_mode]: 
     774                                pjmedia_codec_amrwb_bitrates[s->enc_mode]; 
    718775    } 
    719776#endif 
  • 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 
  • pjproject/trunk/pjmedia/src/pjmedia/endpoint.c

    r2506 r3074  
    128128 
    129129    /* Init codec manager. */ 
    130     status = pjmedia_codec_mgr_init(&endpt->codec_mgr); 
     130    status = pjmedia_codec_mgr_init(&endpt->codec_mgr, endpt->pf); 
    131131    if (status != PJ_SUCCESS) 
    132132        goto on_error; 
     
    173173        pj_ioqueue_destroy(endpt->ioqueue); 
    174174 
     175    pjmedia_codec_mgr_destroy(&endpt->codec_mgr); 
    175176    pjmedia_aud_subsys_shutdown(); 
    176177    pj_pool_release(pool); 
  • pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h

    r3021 r3074  
    44844484 * 
    44854485 * @param codec_id      Codec ID. 
    4486  * @param param         Codec parameter to set. 
     4486 * @param param         Codec parameter to set. Set to NULL to reset 
     4487 *                      codec parameter to library default settings. 
    44874488 * 
    44884489 * @return              PJ_SUCCESS on success, or the appropriate error code. 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c

    r3041 r3074  
    30553055 * Set codec parameters. 
    30563056 */ 
    3057 PJ_DEF(pj_status_t) pjsua_codec_set_param( const pj_str_t *id, 
     3057PJ_DEF(pj_status_t) pjsua_codec_set_param( const pj_str_t *codec_id, 
    30583058                                           const pjmedia_codec_param *param) 
    30593059{ 
    3060     PJ_UNUSED_ARG(id); 
    3061     PJ_UNUSED_ARG(param); 
    3062     PJ_TODO(set_codec_param); 
    3063     return PJ_SUCCESS; 
    3064 } 
     3060    const pjmedia_codec_info *info[2]; 
     3061    pjmedia_codec_mgr *codec_mgr; 
     3062    unsigned count = 2; 
     3063    pj_status_t status; 
     3064 
     3065    codec_mgr = pjmedia_endpt_get_codec_mgr(pjsua_var.med_endpt); 
     3066 
     3067    status = pjmedia_codec_mgr_find_codecs_by_id(codec_mgr, codec_id, 
     3068                                                 &count, info, NULL); 
     3069    if (status != PJ_SUCCESS) 
     3070        return status; 
     3071 
     3072    /* Codec ID should be specific, except for G.722.1 */ 
     3073    if (count > 1 &&  
     3074        pj_strnicmp2(codec_id, "G7221/16", 8) != 0 && 
     3075        pj_strnicmp2(codec_id, "G7221/32", 8) != 0) 
     3076    { 
     3077        pj_assert(!"Codec ID is not specific"); 
     3078        return PJ_ETOOMANY; 
     3079    } 
     3080 
     3081    status = pjmedia_codec_mgr_set_default_param(codec_mgr, info[0], param); 
     3082    return status; 
     3083} 
Note: See TracChangeset for help on using the changeset viewer.