diff options
author | Nanang Izzuddin <nanang@teluu.com> | 2008-08-25 13:58:25 +0000 |
---|---|---|
committer | Nanang Izzuddin <nanang@teluu.com> | 2008-08-25 13:58:25 +0000 |
commit | 920d97341f9c044fd012f6b41fff01e4c9563a16 (patch) | |
tree | d34b163083b56edc8c7196667a05000da4091358 /pjmedia/src/pjmedia-codec | |
parent | 6ddea349e453f1a4147ab10f55726079c1bc4d96 (diff) |
Ticket #599:
- Added "dec_fmtp" and "enc_fmtp" fields to pjmedia_codec_param.setting.
- Codec factory puts its default parameters in "dec_fmtp" field.
- pjmedia_stream_info_from_sdp() puts the "fmtp" attribute in SDP to pjmedia_codec_param.
- Special treatment for fmtp "bitrate" parameter (of G722.1) during SDP negotiation
- Added maxptime field in stream_info.
- Replaced iLBC's fmtp "mode" implementation to use general fmtp mechanism.
- Added some test scripts for G722.1 bitrate negotiation.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2236 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia/src/pjmedia-codec')
-rw-r--r-- | pjmedia/src/pjmedia-codec/ilbc.c | 60 | ||||
-rw-r--r-- | pjmedia/src/pjmedia-codec/ipp_codecs.c | 86 |
2 files changed, 110 insertions, 36 deletions
diff --git a/pjmedia/src/pjmedia-codec/ilbc.c b/pjmedia/src/pjmedia-codec/ilbc.c index 2b8e5fb6..65063167 100644 --- a/pjmedia/src/pjmedia-codec/ilbc.c +++ b/pjmedia/src/pjmedia-codec/ilbc.c @@ -143,7 +143,7 @@ struct ilbc_codec float dec_block[BLOCKL_MAX]; }; - +static pj_str_t STR_MODE = {"mode", 4}; /* * Initialize and register iLBC codec factory to pjmedia endpoint. @@ -273,7 +273,12 @@ static pj_status_t ilbc_default_attr (pjmedia_codec_factory *factory, attr->setting.vad = 1; attr->setting.plc = 1; attr->setting.penh = 1; - attr->setting.dec_fmtp_mode = (pj_uint8_t)ilbc_factory.mode; + attr->setting.dec_fmtp.cnt = 1; + attr->setting.dec_fmtp.param[0].name = STR_MODE; + if (ilbc_factory.mode == 30) + attr->setting.dec_fmtp.param[0].val = pj_str("30"); + else + attr->setting.dec_fmtp.param[0].val = pj_str("20"); return PJ_SUCCESS; } @@ -370,46 +375,65 @@ static pj_status_t ilbc_codec_open(pjmedia_codec *codec, { struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec; pj_status_t status; + unsigned i, dec_fmtp_mode = 0, enc_fmtp_mode = 0; pj_assert(ilbc_codec != NULL); pj_assert(ilbc_codec->enc_ready == PJ_FALSE && ilbc_codec->dec_ready == PJ_FALSE); + /* Get decoder mode */ + for (i = 0; i < attr->setting.dec_fmtp.cnt; ++i) { + if (pj_stricmp(&attr->setting.dec_fmtp.param[i].name, &STR_MODE) == 0) + { + dec_fmtp_mode = (unsigned) + pj_strtoul(&attr->setting.dec_fmtp.param[i].val); + break; + } + } + /* Decoder mode must be set */ - PJ_ASSERT_RETURN(attr->setting.dec_fmtp_mode==20 || - attr->setting.dec_fmtp_mode==30, PJMEDIA_CODEC_EINMODE); + PJ_ASSERT_RETURN(dec_fmtp_mode == 20 || dec_fmtp_mode == 30, + PJMEDIA_CODEC_EINMODE); + + /* Get encoder mode */ + for (i = 0; i < attr->setting.enc_fmtp.cnt; ++i) { + if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name, &STR_MODE) == 0) + { + enc_fmtp_mode = (unsigned) + pj_strtoul(&attr->setting.enc_fmtp.param[i].val); + break; + } + } /* The enc mode must be set in the attribute * (from the mode parameter in fmtp attribute in the SDP * received from remote) */ - if (attr->setting.enc_fmtp_mode == 0) - attr->setting.enc_fmtp_mode = attr->setting.dec_fmtp_mode; + if (enc_fmtp_mode == 0) + enc_fmtp_mode = dec_fmtp_mode; - PJ_ASSERT_RETURN(attr->setting.enc_fmtp_mode==20 || - attr->setting.enc_fmtp_mode==30, PJMEDIA_CODEC_EINMODE); + PJ_ASSERT_RETURN(enc_fmtp_mode==20 || + enc_fmtp_mode==30, PJMEDIA_CODEC_EINMODE); /* Update enc_ptime in the param */ - if (attr->setting.enc_fmtp_mode != attr->setting.dec_fmtp_mode) { - attr->info.enc_ptime = attr->setting.enc_fmtp_mode; + if (enc_fmtp_mode != dec_fmtp_mode) { + attr->info.enc_ptime = (pj_uint16_t)enc_fmtp_mode; } else { attr->info.enc_ptime = 0; } /* Create enc */ - ilbc_codec->enc_frame_size = initEncode(&ilbc_codec->enc, - attr->setting.enc_fmtp_mode); - ilbc_codec->enc_samples_per_frame = CLOCK_RATE*attr->setting.enc_fmtp_mode/ - 1000; + ilbc_codec->enc_frame_size = initEncode(&ilbc_codec->enc, enc_fmtp_mode); + ilbc_codec->enc_samples_per_frame = CLOCK_RATE * enc_fmtp_mode / 1000; ilbc_codec->enc_ready = PJ_TRUE; /* Create decoder */ ilbc_codec->dec_samples_per_frame = initDecode(&ilbc_codec->dec, - attr->setting.dec_fmtp_mode, + dec_fmtp_mode, attr->setting.penh); - if (attr->setting.dec_fmtp_mode == 20) + if (dec_fmtp_mode == 20) ilbc_codec->dec_frame_size = 38; - else if (attr->setting.dec_fmtp_mode == 30) + else if (dec_fmtp_mode == 30) ilbc_codec->dec_frame_size = 50; else { pj_assert(!"Invalid iLBC mode"); @@ -435,7 +459,7 @@ static pj_status_t ilbc_codec_open(pjmedia_codec *codec, PJ_LOG(5,(ilbc_codec->obj_name, "iLBC codec opened, encoder mode=%d, decoder mode=%d", - attr->setting.enc_fmtp_mode, attr->setting.dec_fmtp_mode)); + enc_fmtp_mode, dec_fmtp_mode)); return PJ_SUCCESS; } diff --git a/pjmedia/src/pjmedia-codec/ipp_codecs.c b/pjmedia/src/pjmedia-codec/ipp_codecs.c index 1521b7c8..50926173 100644 --- a/pjmedia/src/pjmedia-codec/ipp_codecs.c +++ b/pjmedia/src/pjmedia-codec/ipp_codecs.c @@ -29,6 +29,7 @@ #include <pj/string.h> #include <pj/os.h> + /* * Only build this file if PJMEDIA_HAS_INTEL_IPP != 0 */ @@ -210,10 +211,12 @@ static struct ipp_codec { int has_native_plc; /* Codec has internal PLC? */ predecode_cb predecode; /* Callback to translate RTP frame - into USC frame */ - parse_cb parse; /* Callback to parse bitstream */ - pack_cb pack; /* Callback to pack bitstream */ -} + into USC frame. */ + parse_cb parse; /* Callback to parse bitstream. */ + pack_cb pack; /* Callback to pack bitstream. */ + + pjmedia_codec_fmtp dec_fmtp; /* Decoder's fmtp params. */ +} ipp_codec[] = { @@ -232,14 +235,8 @@ ipp_codec[] = # endif # if PJMEDIA_HAS_INTEL_IPP_CODEC_G729 - /* G.729 actually has internal VAD, but for now we need to disable it, - * since its RTP packaging (multiple frames per packet) requires - * SID frame to only be occured in the last frame, while controling - * encoder on each loop (to enable/disable VAD) is considered inefficient. - * This should still be interoperable with other implementations. - */ {1, "G729", PJMEDIA_RTP_PT_G729, &USC_G729AFP_Fxns, 8000, 1, 80, - 8000, 11800, 2, 0, 1, + 8000, 11800, 2, 1, 1, &predecode_g729, NULL, NULL }, # endif @@ -279,9 +276,20 @@ ipp_codec[] = # endif # if PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1 - {0, "G7221", PJMEDIA_RTP_PT_G722_1, &USC_G722_Fxns, 16000, 1, 320, - 16000, 32000, 1, 0, 1, - NULL, NULL, NULL + {0, "G7221", PJMEDIA_RTP_PT_G722_1_16, &USC_G722_Fxns, 16000, 1, 320, + 16000, 16000, 1, 0, 1, + NULL, NULL, NULL, + {1, {{{"bitrate", 7}, {"16000", 5}}} } + }, + {1, "G7221", PJMEDIA_RTP_PT_G722_1_24, &USC_G722_Fxns, 16000, 1, 320, + 24000, 24000, 1, 0, 1, + NULL, NULL, NULL, + {1, {{{"bitrate", 7}, {"24000", 5}}} } + }, + {1, "G7221", PJMEDIA_RTP_PT_G722_1_32, &USC_G722_Fxns, 16000, 1, 320, + 32000, 32000, 1, 0, 1, + NULL, NULL, NULL, + {1, {{{"bitrate", 7}, {"32000", 5}}} } }, # endif }; @@ -422,7 +430,8 @@ static pj_status_t ipp_default_attr (pjmedia_codec_factory *factory, pj_str_t name = pj_str((char*)ipp_codec[i].name); if ((pj_stricmp(&id->encoding_name, &name) == 0) && (id->clock_rate == (unsigned)ipp_codec[i].clock_rate) && - (id->channel_cnt == (unsigned)ipp_codec[i].channel_count)) + (id->channel_cnt == (unsigned)ipp_codec[i].channel_count) && + (id->pt == (unsigned)ipp_codec[i].pt)) { attr->info.pt = (pj_uint8_t)id->pt; attr->info.channel_cnt = ipp_codec[i].channel_count; @@ -437,10 +446,22 @@ static pj_status_t ipp_default_attr (pjmedia_codec_factory *factory, attr->setting.frm_per_pkt = ipp_codec[i].frm_per_pkt; /* Default flags. */ - attr->setting.cng = 0; attr->setting.plc = 1; attr->setting.penh= 0; - attr->setting.vad = 1; /* Always disable for now */ + attr->setting.vad = 1; + attr->setting.cng = attr->setting.vad; + attr->setting.dec_fmtp = ipp_codec[i].dec_fmtp; + + if (attr->setting.vad == 0) { +#if PJMEDIA_HAS_INTEL_IPP_CODEC_G729 + if (id->pt == PJMEDIA_RTP_PT_G729) { + /* Signal G729 Annex B is being disabled */ + attr->setting.dec_fmtp.cnt = 1; + pj_strset2(&attr->setting.dec_fmtp.param[0].name, "annexb"); + pj_strset2(&attr->setting.dec_fmtp.param[0].val, "no"); + } +#endif + } return PJ_SUCCESS; } @@ -631,10 +652,24 @@ static pj_status_t ipp_codec_open( pjmedia_codec *codec, /* Setting the encoder params */ codec_data->info->params.direction = USC_ENCODE; codec_data->info->params.modes.vad = attr->setting.vad && - ippc->has_native_vad; + ippc->has_native_vad; codec_data->info->params.modes.bitrate = attr->info.avg_bps; codec_data->info->params.law = 0; /* Linear PCM input */ +#if PJMEDIA_HAS_INTEL_IPP_CODEC_G729 + if (ippc->pt == PJMEDIA_RTP_PT_G729) { + /* Check if G729 Annex B is signaled to be disabled */ + for (i = 0; i < attr->setting.enc_fmtp.cnt; ++i) { + if (pj_stricmp2(&attr->setting.enc_fmtp.param[i].name, "annexb")==0) + { + if (pj_stricmp2(&attr->setting.enc_fmtp.param[i].val, "no")==0) + codec_data->info->params.modes.vad = 0; + break; + } + } + } +#endif + /* Get number of memory blocks needed by the encoder */ if (USC_NoError != ippc->fxns->std.NumAlloc(&codec_data->info->params, &nb_membanks)) @@ -673,6 +708,9 @@ static pj_status_t ipp_codec_open( pjmedia_codec *codec, /* Setting the decoder params */ codec_data->info->params.direction = USC_DECODE; + /* Not sure if VAD affects decoder, just try to be safe */ + codec_data->info->params.modes.vad = ippc->has_native_vad; + /* Get number of memory blocks needed by the decoder */ if (USC_NoError != ippc->fxns->std.NumAlloc(&codec_data->info->params, &nb_membanks)) @@ -925,6 +963,18 @@ static pj_status_t ipp_codec_encode( pjmedia_codec *codec, nsamples -= samples_per_frame; tx += out.nbytes; bits_out += out.nbytes; + +#if PJMEDIA_HAS_INTEL_IPP_CODEC_G729 + if (out.frametype == 1) { + /* SID */ + break; + } else if (out.frametype == 0) { + /* Untransmitted */ + tx -= out.nbytes; + break; + } +#endif + } if (ippc->pack != NULL) { |