summaryrefslogtreecommitdiff
path: root/pjmedia/src/pjmedia-codec/ipp_codecs.c
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2008-10-29 10:17:02 +0000
committerNanang Izzuddin <nanang@teluu.com>2008-10-29 10:17:02 +0000
commitdf432c0c6c3d436fca47bc3a83d46b1603cea182 (patch)
tree8d6dc265ffb50eb0825e3540eec10571ccf4724e /pjmedia/src/pjmedia-codec/ipp_codecs.c
parent53775f4f08beac94a79829d8d3818b3c162d88fe (diff)
Ticket #670:
- Configurable setting to enable/disable AMR bitstream reordering (sensitivity order to/from encoder bits order). - Updated AMR codec to regard in-band Change Mode Request from remote encoder. - Updated AMR settings (octet-align, etc) to be configured upon codec opening, instead of hardcoded in the encode, decode, parse. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2359 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia/src/pjmedia-codec/ipp_codecs.c')
-rw-r--r--pjmedia/src/pjmedia-codec/ipp_codecs.c90
1 files changed, 66 insertions, 24 deletions
diff --git a/pjmedia/src/pjmedia-codec/ipp_codecs.c b/pjmedia/src/pjmedia-codec/ipp_codecs.c
index 57e42c5f..1f044483 100644
--- a/pjmedia/src/pjmedia-codec/ipp_codecs.c
+++ b/pjmedia/src/pjmedia-codec/ipp_codecs.c
@@ -114,6 +114,7 @@ static struct ipp_factory {
/* IPP codecs private data. */
typedef struct ipp_private {
int codec_idx; /**< Codec index. */
+ void *codec_setting; /**< Specific codec setting. */
pj_pool_t *pool; /**< Pool for each instance. */
USC_Handle enc; /**< Encoder state. */
@@ -121,12 +122,14 @@ typedef struct ipp_private {
USC_CodecInfo *info; /**< Native codec info. */
pj_uint16_t frame_size; /**< Bitstream frame size. */
- pj_bool_t plc_enabled;
- pjmedia_plc *plc;
+ pj_bool_t plc_enabled; /**< PLC enabled flag. */
+ pjmedia_plc *plc; /**< PJMEDIA PLC engine, NULL if
+ codec has internal PLC. */
- pj_bool_t vad_enabled;
- pjmedia_silence_det *vad;
- pj_timestamp last_tx;
+ pj_bool_t vad_enabled; /**< VAD enabled flag. */
+ pjmedia_silence_det *vad; /**< PJMEDIA VAD engine, NULL if
+ codec has internal VAD. */
+ pj_timestamp last_tx; /**< Timestamp of last transmit.*/
} ipp_private_t;
@@ -419,6 +422,13 @@ static pj_status_t parse_g723(ipp_private_t *codec_data, void *pkt,
#include <pjmedia-codec/amr_helper.h>
+typedef struct amr_settings_t {
+ pjmedia_codec_amr_settings enc_setting;
+ pjmedia_codec_amr_settings dec_setting;
+ pj_int8_t enc_mode;
+} amr_settings_t;
+
+
/* Rearrange AMR bitstream and convert RTP frame into USC frame:
* - make the start_bit to be 0
* - if it is speech frame, reorder bitstream from sensitivity bits order
@@ -431,17 +441,18 @@ static void predecode_amr( ipp_private_t *codec_data,
{
pjmedia_frame frame;
pjmedia_codec_amr_bit_info *info;
- pj_bool_t amr_nb;
+ pjmedia_codec_amr_settings *setting;
+
+ setting = &((amr_settings_t*)codec_data->codec_setting)->dec_setting;
- amr_nb = (ipp_codec[codec_data->codec_idx].pt == PJMEDIA_RTP_PT_AMR);
frame = *rtp_frame;
- pjmedia_codec_amr_reorder_sens_to_enc(amr_nb, rtp_frame, &frame);
+ pjmedia_codec_amr_predecode(rtp_frame, setting, &frame);
info = (pjmedia_codec_amr_bit_info*) &frame.bit_info;
usc_frame->pBuffer = frame.buf;
usc_frame->nbytes = frame.size;
if (info->mode != -1) {
- usc_frame->bitrate = amr_nb?
+ usc_frame->bitrate = setting->amr_nb?
pjmedia_codec_amrnb_bitrates[info->mode]:
pjmedia_codec_amrwb_bitrates[info->mode];
} else {
@@ -453,7 +464,7 @@ static void predecode_amr( ipp_private_t *codec_data,
if (info->good_quality)
usc_frame->frametype = 0;
else
- usc_frame->frametype = amr_nb ? 5 : 6;
+ usc_frame->frametype = setting->amr_nb ? 5 : 6;
} else if (frame.size == 5) {
/* SID */
if (info->good_quality) {
@@ -461,7 +472,7 @@ static void predecode_amr( ipp_private_t *codec_data,
STI = (((pj_uint8_t*)frame.buf)[35 >> 3] & 0x10) != 0;
usc_frame->frametype = STI? 2 : 1;
} else {
- usc_frame->frametype = amr_nb ? 6 : 7;
+ usc_frame->frametype = setting->amr_nb ? 6 : 7;
}
} else {
/* no data */
@@ -475,18 +486,16 @@ static pj_status_t pack_amr(ipp_private_t *codec_data, void *pkt,
{
enum {MAX_FRAMES_PER_PACKET = 16};
- pjmedia_codec_amr_settings setting;
pjmedia_frame frames[MAX_FRAMES_PER_PACKET];
unsigned nframes = 0;
pjmedia_codec_amr_bit_info *info;
pj_uint8_t *r; /* Read cursor */
pj_uint8_t SID_FT;
+ pjmedia_codec_amr_settings *setting;
- setting.amr_nb = ipp_codec[codec_data->codec_idx].pt == PJMEDIA_RTP_PT_AMR;
- setting.CMR = 15; /* not requesting any mode */
- setting.octet_aligned = 0;
+ setting = &((amr_settings_t*)codec_data->codec_setting)->enc_setting;
- SID_FT = (pj_uint8_t)(setting.amr_nb? 8 : 9);
+ SID_FT = (pj_uint8_t)(setting->amr_nb? 8 : 9);
/* Align pkt buf right */
r = (pj_uint8_t*)pkt + max_pkt_size - *pkt_size;
@@ -520,7 +529,7 @@ static pj_status_t pack_amr(ipp_private_t *codec_data, void *pkt,
/* Pack */
*pkt_size = max_pkt_size;
- return pjmedia_codec_amr_pack(frames, nframes, &setting, pkt, pkt_size);
+ return pjmedia_codec_amr_pack(frames, nframes, setting, pkt, pkt_size);
}
@@ -529,14 +538,24 @@ static pj_status_t parse_amr(ipp_private_t *codec_data, void *pkt,
pj_size_t pkt_size, const pj_timestamp *ts,
unsigned *frame_cnt, pjmedia_frame frames[])
{
- pjmedia_codec_amr_settings setting;
+ amr_settings_t* s = (amr_settings_t*)codec_data->codec_setting;
+ pjmedia_codec_amr_settings *setting;
+ pj_status_t status;
pj_uint8_t CMR;
- setting.amr_nb = ipp_codec[codec_data->codec_idx].pt == PJMEDIA_RTP_PT_AMR;
- setting.octet_aligned = 0;
+ setting = &s->dec_setting;
- return pjmedia_codec_amr_parse(pkt, pkt_size, ts, &setting, frames,
- frame_cnt, &CMR);
+ status = pjmedia_codec_amr_parse(pkt, pkt_size, ts, setting, frames,
+ frame_cnt, &CMR);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Check Change Mode Request. */
+ if ((setting->amr_nb && CMR <= 7) || (!setting->amr_nb && CMR <= 8)) {
+ s->enc_mode = CMR;
+ }
+
+ return PJ_SUCCESS;
}
#endif /* PJMEDIA_HAS_INTEL_IPP_CODEC_AMR */
@@ -1000,6 +1019,29 @@ static pj_status_t ipp_codec_open( pjmedia_codec *codec,
codec_data->vad_enabled = (attr->setting.vad != 0);
codec_data->plc_enabled = (attr->setting.plc != 0);
+#if PJMEDIA_HAS_INTEL_IPP_CODEC_AMR
+ /* Init AMR settings */
+ if (ippc->pt == PJMEDIA_RTP_PT_AMR || ippc->pt == PJMEDIA_RTP_PT_AMRWB) {
+ amr_settings_t *s;
+
+ s = PJ_POOL_ZALLOC_T(pool, amr_settings_t);
+ codec_data->codec_setting = s;
+
+ s->enc_mode = pjmedia_codec_amr_get_mode(ippc->def_bitrate);
+ if (s->enc_mode < 0)
+ goto on_error;
+
+ s->enc_setting.amr_nb = ippc->pt == PJMEDIA_RTP_PT_AMR;
+ s->enc_setting.octet_aligned = 0;
+ s->enc_setting.reorder = PJ_TRUE;
+ s->enc_setting.CMR = 15;
+
+ s->dec_setting.amr_nb = ippc->pt == PJMEDIA_RTP_PT_AMR;
+ s->dec_setting.octet_aligned = 0;
+ s->dec_setting.reorder = PJ_TRUE;
+ }
+#endif
+
return PJ_SUCCESS;
on_error:
@@ -1161,8 +1203,8 @@ static pj_status_t ipp_codec_encode( pjmedia_codec *codec,
}
#if PJMEDIA_HAS_INTEL_IPP_CODEC_AMR
- /* For AMR: put info (frametype, degraded, last frame) in the
- * first byte
+ /* For AMR: put info (frametype, degraded, last frame, mode) in the
+ * first two octets for payload packing.
*/
if (pt == PJMEDIA_RTP_PT_AMR || pt == PJMEDIA_RTP_PT_AMRWB) {
pj_uint16_t *info = (pj_uint16_t*)bits_out;