summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2010-08-10 15:06:40 +0000
committerNanang Izzuddin <nanang@teluu.com>2010-08-10 15:06:40 +0000
commit46dfd83eed46659d23790c39a17b4a3494440c98 (patch)
treead5b62d8f9c15e271d9cd7130b28380dd99a10cf
parent52c88ba30cd5da601d77bdba0bd3e6d3179b72e4 (diff)
Fix #1106:
- Added PCM signal adjustment in IPP G722.1 implementation. The default setting is configurable via (the existing compile-time config) PJMEDIA_G7221_DEFAULT_PCM_SHIFT. - Added new APIs to get and set IPP codecs settings: pjmedia_codec_ipp_set/get_config(). At run-time, the G722.1 PCM signal adjustment setting can be set using these functions. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3261 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjmedia/include/pjmedia-codec/ipp_codecs.h39
-rw-r--r--pjmedia/src/pjmedia-codec/ipp_codecs.c67
2 files changed, 106 insertions, 0 deletions
diff --git a/pjmedia/include/pjmedia-codec/ipp_codecs.h b/pjmedia/include/pjmedia-codec/ipp_codecs.h
index 98eb8a87..42db8a0f 100644
--- a/pjmedia/include/pjmedia-codec/ipp_codecs.h
+++ b/pjmedia/include/pjmedia-codec/ipp_codecs.h
@@ -291,6 +291,24 @@
PJ_BEGIN_DECL
+/**
+ * IPP codecs configuration settings.
+ */
+typedef struct pjmedia_codec_ipp_config
+{
+ /**
+ * Specifies the G.722.1 codec encoder and decoder level adjustment.
+ * If the value is non-zero, then PCM input samples to the encoder will
+ * be shifted right by this value, and similarly PCM output samples from
+ * the decoder will be shifted left by this value.
+ *
+ * Default value is PJMEDIA_G7221_DEFAULT_PCM_SHIFT.
+ */
+ unsigned g7221_pcm_shift;
+
+} pjmedia_codec_ipp_config;
+
+
/**
* Initialize and register IPP codecs factory to pjmedia endpoint.
*
@@ -301,6 +319,27 @@ PJ_BEGIN_DECL
PJ_DECL(pj_status_t) pjmedia_codec_ipp_init( pjmedia_endpt *endpt );
+/**
+ * Get current IPP codecs configuration settings.
+ *
+ * @param cfg The IPP codecs configuration settings buffer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_ipp_get_config(
+ pjmedia_codec_ipp_config *cfg);
+
+
+/**
+ * Set IPP codecs configuration settings.
+ *
+ * @param setting The IPP codecs configuration settings to be applied.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_ipp_set_config(
+ const pjmedia_codec_ipp_config *cfg);
+
/**
* Unregister IPP codecs factory from pjmedia endpoint and deinitialize
diff --git a/pjmedia/src/pjmedia-codec/ipp_codecs.c b/pjmedia/src/pjmedia-codec/ipp_codecs.c
index 54f560e6..86449268 100644
--- a/pjmedia/src/pjmedia-codec/ipp_codecs.c
+++ b/pjmedia/src/pjmedia-codec/ipp_codecs.c
@@ -112,6 +112,7 @@ static struct ipp_factory {
pjmedia_endpt *endpt;
pj_pool_t *pool;
pj_mutex_t *mutex;
+ unsigned g7221_pcm_shift;
} ipp_factory;
/* IPP codecs private data. */
@@ -133,6 +134,8 @@ typedef struct ipp_private {
pjmedia_silence_det *vad; /**< PJMEDIA VAD engine, NULL if
codec has internal VAD. */
pj_timestamp last_tx; /**< Timestamp of last transmit.*/
+
+ unsigned g7221_pcm_shift; /**< G722.1 PCM level adjustment*/
} ipp_private_t;
@@ -660,6 +663,7 @@ PJ_DEF(pj_status_t) pjmedia_codec_ipp_init( pjmedia_endpt *endpt )
ipp_factory.base.op = &ipp_factory_op;
ipp_factory.base.factory_data = NULL;
ipp_factory.endpt = endpt;
+ ipp_factory.g7221_pcm_shift = PJMEDIA_G7221_DEFAULT_PCM_SHIFT;
ipp_factory.pool = pjmedia_endpt_create_pool(endpt, "IPP codecs", 4000, 4000);
if (!ipp_factory.pool)
@@ -730,6 +734,35 @@ PJ_DEF(pj_status_t) pjmedia_codec_ipp_deinit(void)
return status;
}
+/*
+ * Get current IPP codecs configuration settings.
+ */
+PJ_DEF(pj_status_t) pjmedia_codec_ipp_get_config(
+ pjmedia_codec_ipp_config *cfg)
+{
+ PJ_ASSERT_RETURN(cfg, PJ_EINVAL);
+
+ pj_bzero(cfg, sizeof(*cfg));
+ cfg->g7221_pcm_shift = ipp_factory.g7221_pcm_shift;
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Set IPP codecs configuration settings.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_ipp_set_config(
+ const pjmedia_codec_ipp_config *cfg)
+{
+ PJ_ASSERT_RETURN(cfg, PJ_EINVAL);
+
+ ipp_factory.g7221_pcm_shift = cfg->g7221_pcm_shift;
+
+ return PJ_SUCCESS;
+}
+
+
/*
* Check if factory can allocate the specified codec.
*/
@@ -1208,6 +1241,14 @@ static pj_status_t ipp_codec_open( pjmedia_codec *codec,
}
#endif
+#if PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1
+ if (ippc->pt >= PJMEDIA_RTP_PT_G722_1_16 &&
+ ippc->pt <= PJMEDIA_RTP_PT_G7221_RSV2)
+ {
+ codec_data->g7221_pcm_shift = ipp_factory.g7221_pcm_shift;
+ }
+#endif
+
return PJ_SUCCESS;
on_error:
@@ -1364,6 +1405,18 @@ static pj_status_t ipp_codec_encode( pjmedia_codec *codec,
}
#endif
+#if PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1
+ /* For G722.1: adjust the encoder input signal level */
+ if (pt >= PJMEDIA_RTP_PT_G722_1_16 &&
+ pt <= PJMEDIA_RTP_PT_G7221_RSV2 &&
+ codec_data->g7221_pcm_shift)
+ {
+ unsigned i;
+ for (i = 0; i < samples_per_frame; ++i)
+ pcm_in[i] >>= codec_data->g7221_pcm_shift;
+ }
+#endif
+
if (USC_NoError != ippc->fxns->Encode(codec_data->enc, &in, &out)) {
break;
}
@@ -1514,6 +1567,20 @@ static pj_status_t ipp_codec_decode( pjmedia_codec *codec,
}
#endif
+#if PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1
+ /* For G722.1: adjust the decoder output signal level */
+ if (pt >= PJMEDIA_RTP_PT_G722_1_16 &&
+ pt <= PJMEDIA_RTP_PT_G7221_RSV2 &&
+ codec_data->g7221_pcm_shift)
+ {
+ unsigned i;
+ pj_int16_t *s = (pj_int16_t*)output->buf;
+
+ for (i = 0; i < samples_per_frame; ++i)
+ s[i] <<= codec_data->g7221_pcm_shift;
+ }
+#endif
+
output->type = PJMEDIA_FRAME_TYPE_AUDIO;
output->size = samples_per_frame << 1;
output->timestamp.u64 = input->timestamp.u64;