Ticket #910:
- Added a new API pjmedia_codec_passthrough_init2().
- Updated the initialization steps of passthrough codec in pjsua_media.c, to configure the codecs (of passthrough codec) to be enabled based on audio device extended/encoded formats.
- Minor update: added passthrough.h into pjmedia_codec.vcproj.
git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@2825 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjmedia/build/pjmedia_codec.vcproj b/pjmedia/build/pjmedia_codec.vcproj
index aaf4e1c..25cf77b 100644
--- a/pjmedia/build/pjmedia_codec.vcproj
+++ b/pjmedia/build/pjmedia_codec.vcproj
Binary files differ
diff --git a/pjmedia/include/pjmedia-codec/passthrough.h b/pjmedia/include/pjmedia-codec/passthrough.h
index 0705690..7b237c3 100644
--- a/pjmedia/include/pjmedia-codec/passthrough.h
+++ b/pjmedia/include/pjmedia-codec/passthrough.h
@@ -48,8 +48,22 @@
PJ_BEGIN_DECL
+
+/**
+ * Codec passthrough configuration settings.
+ */
+typedef struct pjmedia_codec_passthrough_setting
+{
+ unsigned fmt_cnt; /**< Number of encoding formats
+ to be enabled. */
+ pjmedia_format *fmts; /**< Encoding formats to be
+ enabled. */
+} pjmedia_codec_passthrough_setting;
+
+
/**
- * Initialize and register passthrough codecs factory to pjmedia endpoint.
+ * Initialize and register passthrough codecs factory to pjmedia endpoint,
+ * all supported encoding formats will be enabled.
*
* @param endpt The pjmedia endpoint.
*
@@ -58,6 +72,19 @@
PJ_DECL(pj_status_t) pjmedia_codec_passthrough_init( pjmedia_endpt *endpt );
+/**
+ * Initialize and register passthrough codecs factory to pjmedia endpoint
+ * with only specified encoding formats enabled.
+ *
+ * @param endpt The pjmedia endpoint.
+ * @param setting The settings, see @pjmedia_codec_passthrough_setting.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_passthrough_init2(
+ pjmedia_endpt *endpt,
+ const pjmedia_codec_passthrough_setting *setting);
+
/**
* Unregister passthrough codecs factory from pjmedia endpoint.
diff --git a/pjmedia/src/pjmedia-codec/passthrough.c b/pjmedia/src/pjmedia-codec/passthrough.c
index 3604cb5..e1572f4 100644
--- a/pjmedia/src/pjmedia-codec/passthrough.c
+++ b/pjmedia/src/pjmedia-codec/passthrough.c
@@ -312,7 +312,7 @@
if (codec_factory.pool != NULL) {
/* Already initialized. */
- return PJ_SUCCESS;
+ return PJ_EEXISTS;
}
/* Create passthrough codec factory. */
@@ -354,11 +354,44 @@
}
/*
+ * Initialize and register passthrough codec factory to pjmedia endpoint.
+ */
+PJ_DEF(pj_status_t) pjmedia_codec_passthrough_init2(
+ pjmedia_endpt *endpt,
+ const pjmedia_codec_passthrough_setting *setting)
+{
+ if (codec_factory.pool != NULL) {
+ /* Already initialized. */
+ return PJ_EEXISTS;
+ }
+
+ if (setting != NULL) {
+ unsigned i;
+
+ /* Enable/disable codecs based on the specified encoding formats */
+ for (i = 0; i < PJ_ARRAY_SIZE(codec_desc); ++i) {
+ pj_bool_t enabled = PJ_FALSE;
+ unsigned j;
+
+ for (j = 0; j < setting->fmt_cnt && !enabled; ++j) {
+ if (codec_desc[i].fmt_id == setting->fmts[j].id)
+ enabled = PJ_TRUE;
+ }
+
+ codec_desc[i].enabled = enabled;
+ }
+ }
+
+ return pjmedia_codec_passthrough_init(endpt);
+}
+
+/*
* Unregister passthrough codecs factory from pjmedia endpoint.
*/
PJ_DEF(pj_status_t) pjmedia_codec_passthrough_deinit(void)
{
pjmedia_codec_mgr *codec_mgr;
+ unsigned i;
pj_status_t status;
if (codec_factory.pool == NULL) {
@@ -387,6 +420,11 @@
pj_pool_release(codec_factory.pool);
codec_factory.pool = NULL;
+ /* Re-enable all codecs in the codec_desc. */
+ for (i = 0; i < PJ_ARRAY_SIZE(codec_desc); ++i) {
+ codec_desc[i].enabled = PJ_TRUE;
+ }
+
return status;
}
diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c
index 5496df9..edf13ba 100644
--- a/pjsip/src/pjsua-lib/pjsua_media.c
+++ b/pjsip/src/pjsua-lib/pjsua_media.c
@@ -194,11 +194,55 @@
#if PJMEDIA_HAS_PASSTHROUGH_CODECS
/* Register passthrough codecs */
- status = pjmedia_codec_passthrough_init(pjsua_var.med_endpt);
- if (status != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Error initializing passthrough codecs",
- status);
- return status;
+ {
+ unsigned aud_idx;
+ unsigned ext_fmt_cnt = 0;
+ pjmedia_format ext_fmts[32];
+ pjmedia_codec_passthrough_setting setting;
+
+ /* List extended formats supported by audio devices */
+ for (aud_idx = 0; aud_idx < pjmedia_aud_dev_count(); ++aud_idx) {
+ pjmedia_aud_dev_info aud_info;
+ unsigned i;
+
+ status = pjmedia_aud_dev_get_info(aud_idx, &aud_info);
+ if (status != PJ_SUCCESS) {
+ pjsua_perror(THIS_FILE, "Error querying audio device info",
+ status);
+ return status;
+ }
+
+ /* Collect extended formats supported by this audio device */
+ for (i = 0; i < aud_info.ext_fmt_cnt; ++i) {
+ unsigned j;
+ pj_bool_t is_listed = PJ_FALSE;
+
+ /* See if this extended format is already in the list */
+ for (j = 0; j < ext_fmt_cnt && !is_listed; ++j) {
+ if (ext_fmts[j].id == aud_info.ext_fmt[i].id &&
+ ext_fmts[j].bitrate == aud_info.ext_fmt[i].bitrate)
+ {
+ is_listed = PJ_TRUE;
+ }
+ }
+
+ /* Put this format into the list, if it is not in the list */
+ if (!is_listed)
+ ext_fmts[ext_fmt_cnt++] = aud_info.ext_fmt[i];
+
+ pj_assert(ext_fmt_cnt <= PJ_ARRAY_SIZE(ext_fmts));
+ }
+ }
+
+ /* Init the passthrough codec with supported formats only */
+ setting.fmt_cnt = ext_fmt_cnt;
+ setting.fmts = ext_fmts;
+ status = pjmedia_codec_passthrough_init2(pjsua_var.med_endpt, &setting);
+ if (status != PJ_SUCCESS) {
+ pjsua_perror(THIS_FILE, "Error initializing passthrough codecs",
+ status);
+ return status;
+ }
}
#endif /* PJMEDIA_HAS_PASSTHROUGH_CODECS */