diff options
author | Nanang Izzuddin <nanang@teluu.com> | 2010-01-27 11:48:31 +0000 |
---|---|---|
committer | Nanang Izzuddin <nanang@teluu.com> | 2010-01-27 11:48:31 +0000 |
commit | b4363f43a76411dcdbe60917d6ffe2d168cec3a2 (patch) | |
tree | 40bf7ba236ca1456a5d47360b711936d87d44011 | |
parent | 67983fb24f15e72df308c0e52f7055f38c09615c (diff) |
Ticket #1028: Recommit r3074 with updated codec.h.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3078 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r-- | pjmedia/include/pjmedia/codec.h | 79 | ||||
-rw-r--r-- | pjmedia/src/pjmedia-audiodev/symb_vas_dev.cpp | 4 | ||||
-rw-r--r-- | pjmedia/src/pjmedia-codec/ipp_codecs.c | 3 | ||||
-rw-r--r-- | pjmedia/src/pjmedia-codec/passthrough.c | 49 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/codec.c | 216 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/endpoint.c | 3 | ||||
-rw-r--r-- | pjsip/include/pjsua-lib/pjsua.h | 3 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_media.c | 29 |
8 files changed, 356 insertions, 30 deletions
diff --git a/pjmedia/include/pjmedia/codec.h b/pjmedia/include/pjmedia/codec.h index f0dd77a6..67df9f58 100644 --- a/pjmedia/include/pjmedia/codec.h +++ b/pjmedia/include/pjmedia/codec.h @@ -28,6 +28,7 @@ #include <pjmedia/port.h> #include <pj/list.h> +#include <pj/pool.h> PJ_BEGIN_DECL @@ -244,20 +245,26 @@ typedef struct pjmedia_codec_info /** * Structure of codec specific parameters which contains name=value pairs. * The codec specific parameters are to be used with SDP according to - * the standards (e.g: RFC 3555). + * the standards (e.g: RFC 3555) in SDP 'a=fmtp' attribute. */ typedef struct pjmedia_codec_fmtp { - pj_uint8_t cnt; + pj_uint8_t cnt; /**< Number of parameters. */ struct param { - pj_str_t name; - pj_str_t val; - } param [PJMEDIA_CODEC_MAX_FMTP_CNT]; + pj_str_t name; /**< Parameter name. */ + pj_str_t val; /**< Parameter value. */ + } param [PJMEDIA_CODEC_MAX_FMTP_CNT]; /**< The parameters. */ } pjmedia_codec_fmtp; /** - * Detailed codec attributes used both to configure a codec and to query - * the capability of codec factories. + * Detailed codec attributes used in configuring a codec and in querying + * the capability of codec factories. Default attributes of any codecs could + * be queried using #pjmedia_codec_mgr_get_default_param() and modified + * using #pjmedia_codec_mgr_set_default_param(). + * + * Please note that codec parameter also contains SDP specific setting, + * #dec_fmtp and #enc_fmtp, which may need to be set appropriately based on + * the effective setting. See each codec documentation for more detail. */ typedef struct pjmedia_codec_param { @@ -628,6 +635,11 @@ typedef enum pjmedia_codec_priority typedef char pjmedia_codec_id[32]; +/** + * Opaque declaration of default codecs parameters. + */ +typedef struct pjmedia_codec_default_param pjmedia_codec_default_param; + /** * Codec manager maintains array of these structs for each supported * codec. @@ -638,6 +650,8 @@ struct pjmedia_codec_desc pjmedia_codec_id id; /**< Fully qualified name */ pjmedia_codec_priority prio; /**< Priority. */ pjmedia_codec_factory *factory; /**< The factory. */ + pjmedia_codec_default_param *param; /**< Default codecs + parameters. */ }; @@ -648,14 +662,23 @@ struct pjmedia_codec_desc */ typedef struct pjmedia_codec_mgr { + /** Media endpoint instance. */ + pj_pool_factory *pf; + + /** Codec manager pool. */ + pj_pool_t *pool; + + /** Codec manager mutex. */ + pj_mutex_t *mutex; + /** List of codec factories registered to codec manager. */ - pjmedia_codec_factory factory_list; + pjmedia_codec_factory factory_list; - /** Number of supported codesc. */ - unsigned codec_cnt; + /** Number of supported codecs. */ + unsigned codec_cnt; /** Array of codec descriptor. */ - struct pjmedia_codec_desc codec_desc[PJMEDIA_CODEC_MGR_MAX_CODECS]; + struct pjmedia_codec_desc codec_desc[PJMEDIA_CODEC_MGR_MAX_CODECS]; } pjmedia_codec_mgr; @@ -666,10 +689,23 @@ typedef struct pjmedia_codec_mgr * endpoint's initialization code. * * @param mgr Codec manager instance. + * @param pf Pool factory instance. + * + * @return PJ_SUCCESS on success. + */ +PJ_DECL(pj_status_t) pjmedia_codec_mgr_init(pjmedia_codec_mgr *mgr, + pj_pool_factory *pf); + + +/** + * Destroy codec manager. Normally this function is called by pjmedia + * endpoint's deinitialization code. + * + * @param mgr Codec manager instance. * * @return PJ_SUCCESS on success. */ -PJ_DECL(pj_status_t) pjmedia_codec_mgr_init(pjmedia_codec_mgr *mgr); +PJ_DECL(pj_status_t) pjmedia_codec_mgr_destroy(pjmedia_codec_mgr *mgr); /** @@ -821,6 +857,25 @@ pjmedia_codec_mgr_get_default_param( pjmedia_codec_mgr *mgr, const pjmedia_codec_info *info, pjmedia_codec_param *param ); + +/** + * Set default codec param for the specified codec info. + * + * @param mgr The codec manager instance. Application can get the + * instance by calling #pjmedia_endpt_get_codec_mgr(). + * @param info The codec info, which default parameter's is being + * updated. + * @param param The new default codec parameter. Set to NULL to reset + * codec parameter to library default settings. + * + * @return PJ_SUCCESS on success. + */ +PJ_DECL(pj_status_t) +pjmedia_codec_mgr_set_default_param( pjmedia_codec_mgr *mgr, + const pjmedia_codec_info *info, + const pjmedia_codec_param *param ); + + /** * Request the codec manager to allocate one instance of codec with the * specified codec info. The codec will enumerate all codec factories diff --git a/pjmedia/src/pjmedia-audiodev/symb_vas_dev.cpp b/pjmedia/src/pjmedia-audiodev/symb_vas_dev.cpp index 776fdbf8..ae9b43c6 100644 --- a/pjmedia/src/pjmedia-audiodev/symb_vas_dev.cpp +++ b/pjmedia/src/pjmedia-audiodev/symb_vas_dev.cpp @@ -491,6 +491,10 @@ TInt CPjAudioEngine::StartRec() } break; + case EAMR_NB: + enc_fmt_if->SetBitRate(setting_.mode); + break; + default: break; } diff --git a/pjmedia/src/pjmedia-codec/ipp_codecs.c b/pjmedia/src/pjmedia-codec/ipp_codecs.c index aaf1142f..a8b73180 100644 --- a/pjmedia/src/pjmedia-codec/ipp_codecs.c +++ b/pjmedia/src/pjmedia-codec/ipp_codecs.c @@ -1195,6 +1195,9 @@ static pj_status_t ipp_codec_open( pjmedia_codec *codec, (s->enc_setting.amr_nb?"":"-WB"), s->enc_mode, codec_data->info->params.modes.bitrate)); + + /* Return back bitrate info to application */ + attr->info.avg_bps = codec_data->info->params.modes.bitrate; } #endif diff --git a/pjmedia/src/pjmedia-codec/passthrough.c b/pjmedia/src/pjmedia-codec/passthrough.c index 06e4de69..bcd8f81a 100644 --- a/pjmedia/src/pjmedia-codec/passthrough.c +++ b/pjmedia/src/pjmedia-codec/passthrough.c @@ -24,6 +24,7 @@ #include <pjmedia/port.h> #include <pj/assert.h> #include <pj/log.h> +#include <pj/math.h> #include <pj/pool.h> #include <pj/string.h> #include <pj/os.h> @@ -696,10 +697,56 @@ static pj_status_t codec_open( pjmedia_codec *codec, } } + for (i = 0; i < attr->setting.enc_fmtp.cnt; ++i) { + /* mode-set, encoding mode is chosen based on local default mode + * setting: + * - if local default mode is included in the mode-set, use it + * - otherwise, find the closest mode to local default mode; + * if there are two closest modes, prefer to use the higher + * one, e.g: local default mode is 4, the mode-set param + * contains '2,3,5,6', then 5 will be chosen. + */ + const pj_str_t STR_FMTP_MODE_SET = {"mode-set", 8}; + + if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name, + &STR_FMTP_MODE_SET) == 0) + { + const char *p; + pj_size_t l; + pj_int8_t diff = 99; + + p = pj_strbuf(&attr->setting.enc_fmtp.param[i].val); + l = pj_strlen(&attr->setting.enc_fmtp.param[i].val); + + while (l--) { + if ((desc->pt==PJMEDIA_RTP_PT_AMR && *p>='0' && *p<='7') || + (desc->pt==PJMEDIA_RTP_PT_AMRWB && *p>='0' && *p<='8')) + { + pj_int8_t tmp = (pj_int8_t)(*p - '0' - enc_mode); + + if (PJ_ABS(diff) > PJ_ABS(tmp) || + (PJ_ABS(diff) == PJ_ABS(tmp) && tmp > diff)) + { + diff = tmp; + if (diff == 0) break; + } + } + ++p; + } + + if (diff == 99) + return PJMEDIA_CODEC_EFAILED; + + enc_mode = (pj_int8_t)(enc_mode + diff); + + break; + } + } + s = PJ_POOL_ZALLOC_T(pool, amr_settings_t); codec_data->codec_setting = s; - s->enc_mode = pjmedia_codec_amr_get_mode(desc->def_bitrate); + s->enc_mode = enc_mode; if (s->enc_mode < 0) return PJMEDIA_CODEC_EINMODE; diff --git a/pjmedia/src/pjmedia/codec.c b/pjmedia/src/pjmedia/codec.c index 708f06e8..d65ede4e 100644 --- a/pjmedia/src/pjmedia/codec.c +++ b/pjmedia/src/pjmedia/codec.c @@ -22,13 +22,19 @@ #include <pj/array.h> #include <pj/assert.h> #include <pj/log.h> -#include <pj/pool.h> #include <pj/string.h> #define THIS_FILE "codec.c" +/* Definition of default codecs parameters */ +struct pjmedia_codec_default_param +{ + pj_pool_t *pool; + pjmedia_codec_param *param; +}; + /* Sort codecs in codec manager based on priorities */ static void sort_codecs(pjmedia_codec_mgr *mgr); @@ -37,13 +43,56 @@ static void sort_codecs(pjmedia_codec_mgr *mgr); /* * Initialize codec manager. */ -PJ_DEF(pj_status_t) pjmedia_codec_mgr_init (pjmedia_codec_mgr *mgr) +PJ_DEF(pj_status_t) pjmedia_codec_mgr_init (pjmedia_codec_mgr *mgr, + pj_pool_factory *pf) { - PJ_ASSERT_RETURN(mgr, PJ_EINVAL); + pj_status_t status; + + PJ_ASSERT_RETURN(mgr && pf, PJ_EINVAL); + /* Init codec manager */ + pj_bzero(mgr, sizeof(pjmedia_codec_mgr)); + mgr->pf = pf; pj_list_init (&mgr->factory_list); mgr->codec_cnt = 0; + /* Create pool */ + mgr->pool = pj_pool_create(mgr->pf, "codec-mgr", 256, 256, NULL); + + /* Create mutex */ + status = pj_mutex_create_recursive(mgr->pool, "codec-mgr", &mgr->mutex); + if (status != PJ_SUCCESS) + return status; + + return PJ_SUCCESS; +} + +/* + * Initialize codec manager. + */ +PJ_DEF(pj_status_t) pjmedia_codec_mgr_destroy (pjmedia_codec_mgr *mgr) +{ + unsigned i; + + PJ_ASSERT_RETURN(mgr, PJ_EINVAL); + + /* Cleanup all pools of all codec default params */ + for (i=0; i<mgr->codec_cnt; ++i) { + if (mgr->codec_desc[i].param) { + pj_assert(mgr->codec_desc[i].param->pool); + pj_pool_release(mgr->codec_desc[i].param->pool); + } + } + + /* Destroy mutex */ + pj_mutex_destroy(mgr->mutex); + + /* Release pool */ + pj_pool_release(mgr->pool); + + /* Just for safety, set codec manager states to zero */ + pj_bzero(mgr, sizeof(pjmedia_codec_mgr)); + return PJ_SUCCESS; } @@ -65,11 +114,14 @@ PJ_DEF(pj_status_t) pjmedia_codec_mgr_register_factory( pjmedia_codec_mgr *mgr, status = factory->op->enum_info(factory, &count, info); if (status != PJ_SUCCESS) return status; - + + pj_mutex_lock(mgr->mutex); /* Check codec count */ - if (count + mgr->codec_cnt > PJ_ARRAY_SIZE(mgr->codec_desc)) + if (count + mgr->codec_cnt > PJ_ARRAY_SIZE(mgr->codec_desc)) { + pj_mutex_unlock(mgr->mutex); return PJ_ETOOMANY; + } /* Save the codecs */ @@ -92,6 +144,7 @@ PJ_DEF(pj_status_t) pjmedia_codec_mgr_register_factory( pjmedia_codec_mgr *mgr, /* Add factory to the list */ pj_list_push_back(&mgr->factory_list, factory); + pj_mutex_unlock(mgr->mutex); return PJ_SUCCESS; } @@ -107,9 +160,13 @@ PJ_DEF(pj_status_t) pjmedia_codec_mgr_unregister_factory( unsigned i; PJ_ASSERT_RETURN(mgr && factory, PJ_EINVAL); + pj_mutex_lock(mgr->mutex); + /* Factory must be registered. */ - PJ_ASSERT_RETURN(pj_list_find_node(&mgr->factory_list, factory)==factory, - PJ_ENOTFOUND); + if (pj_list_find_node(&mgr->factory_list, factory) != factory) { + pj_mutex_unlock(mgr->mutex); + return PJ_ENOTFOUND; + } /* Erase factory from the factory list */ pj_list_erase(factory); @@ -121,7 +178,13 @@ PJ_DEF(pj_status_t) pjmedia_codec_mgr_unregister_factory( for (i=0; i<mgr->codec_cnt; ) { if (mgr->codec_desc[i].factory == factory) { + /* Release pool of codec default param */ + if (mgr->codec_desc[i].param) { + pj_assert(mgr->codec_desc[i].param->pool); + pj_pool_release(mgr->codec_desc[i].param->pool); + } + /* Remove the codec from array of codec descriptions */ pj_array_erase(mgr->codec_desc, sizeof(mgr->codec_desc[0]), mgr->codec_cnt, i); --mgr->codec_cnt; @@ -131,6 +194,7 @@ PJ_DEF(pj_status_t) pjmedia_codec_mgr_unregister_factory( } } + pj_mutex_unlock(mgr->mutex); return PJ_SUCCESS; } @@ -148,6 +212,8 @@ PJ_DEF(pj_status_t) pjmedia_codec_mgr_enum_codecs(pjmedia_codec_mgr *mgr, PJ_ASSERT_RETURN(mgr && count && codecs, PJ_EINVAL); + pj_mutex_lock(mgr->mutex); + if (*count > mgr->codec_cnt) *count = mgr->codec_cnt; @@ -162,6 +228,8 @@ PJ_DEF(pj_status_t) pjmedia_codec_mgr_enum_codecs(pjmedia_codec_mgr *mgr, prio[i] = mgr->codec_desc[i].prio; } + pj_mutex_unlock(mgr->mutex); + return PJ_SUCCESS; } @@ -177,13 +245,19 @@ PJ_DEF(pj_status_t) pjmedia_codec_mgr_get_codec_info( pjmedia_codec_mgr *mgr, PJ_ASSERT_RETURN(mgr && p_info && pt>=0 && pt < 96, PJ_EINVAL); + pj_mutex_lock(mgr->mutex); + for (i=0; i<mgr->codec_cnt; ++i) { if (mgr->codec_desc[i].info.pt == pt) { *p_info = &mgr->codec_desc[i].info; + + pj_mutex_unlock(mgr->mutex); return PJ_SUCCESS; } } + pj_mutex_unlock(mgr->mutex); + return PJMEDIA_CODEC_EUNSUP; } @@ -230,6 +304,8 @@ PJ_DEF(pj_status_t) pjmedia_codec_mgr_find_codecs_by_id( pjmedia_codec_mgr *mgr, PJ_ASSERT_RETURN(mgr && codec_id && count && *count, PJ_EINVAL); + pj_mutex_lock(mgr->mutex); + for (i=0; i<mgr->codec_cnt; ++i) { if (codec_id->slen == 0 || @@ -250,6 +326,8 @@ PJ_DEF(pj_status_t) pjmedia_codec_mgr_find_codecs_by_id( pjmedia_codec_mgr *mgr, } + pj_mutex_unlock(mgr->mutex); + *count = found; return found ? PJ_SUCCESS : PJ_ENOTFOUND; @@ -313,6 +391,8 @@ PJ_DEF(pj_status_t) pjmedia_codec_mgr_set_codec_priority( PJ_ASSERT_RETURN(mgr && codec_id, PJ_EINVAL); + pj_mutex_lock(mgr->mutex); + /* Update the priorities of affected codecs */ for (i=0; i<mgr->codec_cnt; ++i) { @@ -325,12 +405,15 @@ PJ_DEF(pj_status_t) pjmedia_codec_mgr_set_codec_priority( } } - if (!found) + if (!found) { + pj_mutex_unlock(mgr->mutex); return PJ_ENOTFOUND; + } /* Re-sort codecs */ sort_codecs(mgr); - + + pj_mutex_unlock(mgr->mutex); return PJ_SUCCESS; } @@ -350,20 +433,25 @@ PJ_DEF(pj_status_t) pjmedia_codec_mgr_alloc_codec(pjmedia_codec_mgr *mgr, *p_codec = NULL; + pj_mutex_lock(mgr->mutex); + factory = mgr->factory_list.next; while (factory != &mgr->factory_list) { if ( (*factory->op->test_alloc)(factory, info) == PJ_SUCCESS ) { status = (*factory->op->alloc_codec)(factory, info, p_codec); - if (status == PJ_SUCCESS) + if (status == PJ_SUCCESS) { + pj_mutex_unlock(mgr->mutex); return PJ_SUCCESS; + } } factory = factory->next; } + pj_mutex_unlock(mgr->mutex); return PJMEDIA_CODEC_EUNSUP; } @@ -378,9 +466,36 @@ PJ_DEF(pj_status_t) pjmedia_codec_mgr_get_default_param( pjmedia_codec_mgr *mgr, { pjmedia_codec_factory *factory; pj_status_t status; + pjmedia_codec_id codec_id; + struct pjmedia_codec_desc *codec_desc = NULL; + unsigned i; PJ_ASSERT_RETURN(mgr && info && param, PJ_EINVAL); + if (!pjmedia_codec_info_to_id(info, (char*)&codec_id, sizeof(codec_id))) + return PJ_EINVAL; + + pj_mutex_lock(mgr->mutex); + + /* First, lookup default param in codec desc */ + for (i=0; i < mgr->codec_cnt; ++i) { + if (pj_ansi_stricmp(codec_id, mgr->codec_desc[i].id) == 0) { + codec_desc = &mgr->codec_desc[i]; + break; + } + } + + /* If we found the codec and its default param is set, return it */ + if (codec_desc && codec_desc->param) { + pj_assert(codec_desc->param->param); + pj_memcpy(param, codec_desc->param->param, + sizeof(pjmedia_codec_param)); + + pj_mutex_unlock(mgr->mutex); + return PJ_SUCCESS; + } + + /* Otherwise query the default param from codec factory */ factory = mgr->factory_list.next; while (factory != &mgr->factory_list) { @@ -392,6 +507,7 @@ PJ_DEF(pj_status_t) pjmedia_codec_mgr_get_default_param( pjmedia_codec_mgr *mgr, if (param->info.max_bps < param->info.avg_bps) param->info.max_bps = param->info.avg_bps; + pj_mutex_unlock(mgr->mutex); return PJ_SUCCESS; } @@ -400,12 +516,92 @@ PJ_DEF(pj_status_t) pjmedia_codec_mgr_get_default_param( pjmedia_codec_mgr *mgr, factory = factory->next; } + pj_mutex_unlock(mgr->mutex); + return PJMEDIA_CODEC_EUNSUP; } /* + * Set default codec parameter. + */ +PJ_DEF(pj_status_t) pjmedia_codec_mgr_set_default_param( + pjmedia_codec_mgr *mgr, + const pjmedia_codec_info *info, + const pjmedia_codec_param *param ) +{ + unsigned i; + pjmedia_codec_id codec_id; + pj_pool_t *pool; + struct pjmedia_codec_desc *codec_desc = NULL; + pjmedia_codec_default_param *p; + + PJ_ASSERT_RETURN(mgr && info, PJ_EINVAL); + + if (!pjmedia_codec_info_to_id(info, (char*)&codec_id, sizeof(codec_id))) + return PJ_EINVAL; + + pj_mutex_lock(mgr->mutex); + + /* Lookup codec desc */ + for (i=0; i < mgr->codec_cnt; ++i) { + if (pj_ansi_stricmp(codec_id, mgr->codec_desc[i].id) == 0) { + codec_desc = &mgr->codec_desc[i]; + break; + } + } + + /* Codec not found */ + if (!codec_desc) { + pj_mutex_unlock(mgr->mutex); + return PJMEDIA_CODEC_EUNSUP; + } + + /* If codec param is previously set, release codec param pool */ + if (codec_desc->param) { + pj_assert(codec_desc->param->pool); + pj_pool_release(codec_desc->param->pool); + codec_desc->param = NULL; + } + + /* When param is set to NULL, i.e: setting default codec param to library + * default setting, just return PJ_SUCCESS. + */ + if (NULL == param) { + pj_mutex_unlock(mgr->mutex); + return PJ_SUCCESS; + } + + /* Instantiate and initialize codec param */ + pool = pj_pool_create(mgr->pf, (char*)codec_id, 256, 256, NULL); + codec_desc->param = PJ_POOL_ZALLOC_T(pool, pjmedia_codec_default_param); + p = codec_desc->param; + p->pool = pool; + p->param = PJ_POOL_ZALLOC_T(pool, pjmedia_codec_param); + + /* Update codec param */ + pj_memcpy(p->param, param, sizeof(pjmedia_codec_param)); + for (i = 0; i < param->setting.dec_fmtp.cnt; ++i) { + pj_strdup(pool, &p->param->setting.dec_fmtp.param[i].name, + ¶m->setting.dec_fmtp.param[i].name); + pj_strdup(pool, &p->param->setting.dec_fmtp.param[i].val, + ¶m->setting.dec_fmtp.param[i].val); + } + for (i = 0; i < param->setting.dec_fmtp.cnt; ++i) { + pj_strdup(pool, &p->param->setting.dec_fmtp.param[i].name, + ¶m->setting.dec_fmtp.param[i].name); + pj_strdup(pool, &p->param->setting.dec_fmtp.param[i].val, + ¶m->setting.dec_fmtp.param[i].val); + } + + pj_mutex_unlock(mgr->mutex); + + return PJ_SUCCESS; +} + + +/* * Dealloc codec. */ PJ_DEF(pj_status_t) pjmedia_codec_mgr_dealloc_codec(pjmedia_codec_mgr *mgr, diff --git a/pjmedia/src/pjmedia/endpoint.c b/pjmedia/src/pjmedia/endpoint.c index a3e988d5..8840589d 100644 --- a/pjmedia/src/pjmedia/endpoint.c +++ b/pjmedia/src/pjmedia/endpoint.c @@ -127,7 +127,7 @@ PJ_DEF(pj_status_t) pjmedia_endpt_create(pj_pool_factory *pf, goto on_error; /* Init codec manager. */ - status = pjmedia_codec_mgr_init(&endpt->codec_mgr); + status = pjmedia_codec_mgr_init(&endpt->codec_mgr, endpt->pf); if (status != PJ_SUCCESS) goto on_error; @@ -172,6 +172,7 @@ on_error: if (endpt->ioqueue && endpt->own_ioqueue) pj_ioqueue_destroy(endpt->ioqueue); + pjmedia_codec_mgr_destroy(&endpt->codec_mgr); pjmedia_aud_subsys_shutdown(); pj_pool_release(pool); return status; diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h index 44ce9f0f..ecafb25d 100644 --- a/pjsip/include/pjsua-lib/pjsua.h +++ b/pjsip/include/pjsua-lib/pjsua.h @@ -4483,7 +4483,8 @@ PJ_DECL(pj_status_t) pjsua_codec_get_param( const pj_str_t *codec_id, * Set codec parameters. * * @param codec_id Codec ID. - * @param param Codec parameter to set. + * @param param Codec parameter to set. Set to NULL to reset + * codec parameter to library default settings. * * @return PJ_SUCCESS on success, or the appropriate error code. */ diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c index 3a6bb04f..234833b6 100644 --- a/pjsip/src/pjsua-lib/pjsua_media.c +++ b/pjsip/src/pjsua-lib/pjsua_media.c @@ -3054,11 +3054,30 @@ PJ_DEF(pj_status_t) pjsua_codec_get_param( const pj_str_t *codec_id, /* * Set codec parameters. */ -PJ_DEF(pj_status_t) pjsua_codec_set_param( const pj_str_t *id, +PJ_DEF(pj_status_t) pjsua_codec_set_param( const pj_str_t *codec_id, const pjmedia_codec_param *param) { - PJ_UNUSED_ARG(id); - PJ_UNUSED_ARG(param); - PJ_TODO(set_codec_param); - return PJ_SUCCESS; + const pjmedia_codec_info *info[2]; + pjmedia_codec_mgr *codec_mgr; + unsigned count = 2; + pj_status_t status; + + codec_mgr = pjmedia_endpt_get_codec_mgr(pjsua_var.med_endpt); + + status = pjmedia_codec_mgr_find_codecs_by_id(codec_mgr, codec_id, + &count, info, NULL); + if (status != PJ_SUCCESS) + return status; + + /* Codec ID should be specific, except for G.722.1 */ + if (count > 1 && + pj_strnicmp2(codec_id, "G7221/16", 8) != 0 && + pj_strnicmp2(codec_id, "G7221/32", 8) != 0) + { + pj_assert(!"Codec ID is not specific"); + return PJ_ETOOMANY; + } + + status = pjmedia_codec_mgr_set_default_param(codec_mgr, info[0], param); + return status; } |