summaryrefslogtreecommitdiff
path: root/pjmedia
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2008-06-06 12:15:23 +0000
committerNanang Izzuddin <nanang@teluu.com>2008-06-06 12:15:23 +0000
commit70e0bfbb16138e426e270b15919ca333de352e6b (patch)
tree0f5b6c28d0708a0327b68798fc1b86d60cb08bc7 /pjmedia
parent98065b76fa28cd414b122f3623cbc9d93b898d42 (diff)
Added field maximum bitrate to codec param, this is useful for providing safer frame size calculation, especially when peer's bitrate is unknown
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1985 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia')
-rw-r--r--pjmedia/include/pjmedia/codec.h1
-rw-r--r--pjmedia/src/pjmedia-codec/g722.c1
-rw-r--r--pjmedia/src/pjmedia-codec/gsm.c1
-rw-r--r--pjmedia/src/pjmedia-codec/ilbc.c1
-rw-r--r--pjmedia/src/pjmedia-codec/l16.c1
-rw-r--r--pjmedia/src/pjmedia-codec/speex_codec.c23
-rw-r--r--pjmedia/src/pjmedia/codec.c7
-rw-r--r--pjmedia/src/pjmedia/g711.c1
-rw-r--r--pjmedia/src/pjmedia/stream.c30
9 files changed, 49 insertions, 17 deletions
diff --git a/pjmedia/include/pjmedia/codec.h b/pjmedia/include/pjmedia/codec.h
index 1a7e0bc0..d3e08927 100644
--- a/pjmedia/include/pjmedia/codec.h
+++ b/pjmedia/include/pjmedia/codec.h
@@ -253,6 +253,7 @@ typedef struct pjmedia_codec_param
unsigned clock_rate; /**< Sampling rate in Hz */
unsigned channel_cnt; /**< Channel count. */
pj_uint32_t avg_bps; /**< Average bandwidth in bits/sec */
+ pj_uint32_t max_bps; /**< Maximum bandwidth in bits/sec */
pj_uint16_t frm_ptime; /**< Decoder frame ptime in msec. */
pj_uint16_t enc_ptime; /**< Encoder ptime, or zero if it's
equal to decoder ptime. */
diff --git a/pjmedia/src/pjmedia-codec/g722.c b/pjmedia/src/pjmedia-codec/g722.c
index aa54c177..cc1afa1f 100644
--- a/pjmedia/src/pjmedia-codec/g722.c
+++ b/pjmedia/src/pjmedia-codec/g722.c
@@ -270,6 +270,7 @@ static pj_status_t g722_default_attr( pjmedia_codec_factory *factory,
attr->info.clock_rate = 16000;
attr->info.channel_cnt = 1;
attr->info.avg_bps = 64000;
+ attr->info.max_bps = 64000;
attr->info.pcm_bits_per_sample = 16;
attr->info.frm_ptime = PTIME;
attr->info.pt = PJMEDIA_RTP_PT_G722;
diff --git a/pjmedia/src/pjmedia-codec/gsm.c b/pjmedia/src/pjmedia-codec/gsm.c
index 555901f8..5dc2034e 100644
--- a/pjmedia/src/pjmedia-codec/gsm.c
+++ b/pjmedia/src/pjmedia-codec/gsm.c
@@ -264,6 +264,7 @@ static pj_status_t gsm_default_attr (pjmedia_codec_factory *factory,
attr->info.clock_rate = 8000;
attr->info.channel_cnt = 1;
attr->info.avg_bps = 13200;
+ attr->info.max_bps = 13200;
attr->info.pcm_bits_per_sample = 16;
attr->info.frm_ptime = 20;
attr->info.pt = PJMEDIA_RTP_PT_GSM;
diff --git a/pjmedia/src/pjmedia-codec/ilbc.c b/pjmedia/src/pjmedia-codec/ilbc.c
index 2134e77b..e14647ec 100644
--- a/pjmedia/src/pjmedia-codec/ilbc.c
+++ b/pjmedia/src/pjmedia-codec/ilbc.c
@@ -264,6 +264,7 @@ static pj_status_t ilbc_default_attr (pjmedia_codec_factory *factory,
attr->info.clock_rate = CLOCK_RATE;
attr->info.channel_cnt = 1;
attr->info.avg_bps = ilbc_factory.bps;
+ attr->info.max_bps = 15200;
attr->info.pcm_bits_per_sample = 16;
attr->info.frm_ptime = (short)ilbc_factory.mode;
attr->info.pt = PJMEDIA_RTP_PT_ILBC;
diff --git a/pjmedia/src/pjmedia-codec/l16.c b/pjmedia/src/pjmedia-codec/l16.c
index 0ccc9309..5ddd0443 100644
--- a/pjmedia/src/pjmedia-codec/l16.c
+++ b/pjmedia/src/pjmedia-codec/l16.c
@@ -242,6 +242,7 @@ static pj_status_t l16_default_attr( pjmedia_codec_factory *factory,
attr->info.clock_rate = id->clock_rate;
attr->info.channel_cnt = id->channel_cnt;
attr->info.avg_bps = id->clock_rate * id->channel_cnt * 16;
+ attr->info.max_bps = attr->info.avg_bps;
attr->info.pcm_bits_per_sample = 16;
/* To keep frame size below 1400 MTU, set ptime to 10ms for
diff --git a/pjmedia/src/pjmedia-codec/speex_codec.c b/pjmedia/src/pjmedia-codec/speex_codec.c
index 05d6b67b..0e8f5e38 100644
--- a/pjmedia/src/pjmedia-codec/speex_codec.c
+++ b/pjmedia/src/pjmedia-codec/speex_codec.c
@@ -121,6 +121,7 @@ struct speex_param
int samples_per_frame; /* Samples per frame. */
int framesize; /* Frame size for current mode. */
int bitrate; /* Bit rate for current mode. */
+ int max_bitrate; /* Max bit rate for current mode. */
};
/* Speex factory */
@@ -160,9 +161,9 @@ static pj_status_t get_speex_info( struct speex_param *p )
if (!state)
return PJMEDIA_CODEC_EFAILED;
- /* We have to get maximum bitrate, so let's set maximum quality */
- tmp = 10;
- speex_encoder_ctl(state, SPEEX_SET_QUALITY, &tmp);
+ /* Set the quality */
+ if (p->quality != -1)
+ speex_encoder_ctl(state, SPEEX_SET_QUALITY, &p->quality);
/* Sampling rate. */
speex_encoder_ctl(state, SPEEX_SET_SAMPLING_RATE, &p->clock_rate);
@@ -178,12 +179,17 @@ static pj_status_t get_speex_info( struct speex_param *p )
/* Now get the frame size */
speex_encoder_ctl(state, SPEEX_GET_FRAME_SIZE, &p->samples_per_frame);
- /* Now get the the averate bitrate */
+ /* Now get the average bitrate */
speex_encoder_ctl(state, SPEEX_GET_BITRATE, &p->bitrate);
/* Calculate framesize. */
p->framesize = p->bitrate * 20 / 1000;
+ /* Now get the maximum bitrate by using maximum quality (=10) */
+ tmp = 10;
+ speex_encoder_ctl(state, SPEEX_SET_QUALITY, &tmp);
+ speex_encoder_ctl(state, SPEEX_GET_BITRATE, &p->max_bitrate);
+
/* Destroy encoder. */
speex_encoder_destroy(state);
@@ -237,7 +243,7 @@ PJ_DEF(pj_status_t) pjmedia_codec_speex_init( pjmedia_endpt *endpt,
spx_factory.speex_param[PARAM_NB].enabled =
((options & PJMEDIA_SPEEX_NO_NB) == 0);
spx_factory.speex_param[PARAM_NB].pt = PJMEDIA_RTP_PT_SPEEX_NB;
- spx_factory.speex_param[PARAM_NB].mode = &speex_nb_mode;
+ spx_factory.speex_param[PARAM_NB].mode = speex_lib_get_mode(SPEEX_MODEID_NB);
spx_factory.speex_param[PARAM_NB].clock_rate = 8000;
spx_factory.speex_param[PARAM_NB].quality = quality;
spx_factory.speex_param[PARAM_NB].complexity = complexity;
@@ -245,7 +251,7 @@ PJ_DEF(pj_status_t) pjmedia_codec_speex_init( pjmedia_endpt *endpt,
spx_factory.speex_param[PARAM_WB].enabled =
((options & PJMEDIA_SPEEX_NO_WB) == 0);
spx_factory.speex_param[PARAM_WB].pt = PJMEDIA_RTP_PT_SPEEX_WB;
- spx_factory.speex_param[PARAM_WB].mode = &speex_wb_mode;
+ spx_factory.speex_param[PARAM_WB].mode = speex_lib_get_mode(SPEEX_MODEID_WB);
spx_factory.speex_param[PARAM_WB].clock_rate = 16000;
spx_factory.speex_param[PARAM_WB].quality = quality;
spx_factory.speex_param[PARAM_WB].complexity = complexity;
@@ -253,7 +259,7 @@ PJ_DEF(pj_status_t) pjmedia_codec_speex_init( pjmedia_endpt *endpt,
spx_factory.speex_param[PARAM_UWB].enabled =
((options & PJMEDIA_SPEEX_NO_UWB) == 0);
spx_factory.speex_param[PARAM_UWB].pt = PJMEDIA_RTP_PT_SPEEX_UWB;
- spx_factory.speex_param[PARAM_UWB].mode = &speex_uwb_mode;
+ spx_factory.speex_param[PARAM_UWB].mode = speex_lib_get_mode(SPEEX_MODEID_UWB);
spx_factory.speex_param[PARAM_UWB].clock_rate = 32000;
spx_factory.speex_param[PARAM_UWB].quality = quality;
spx_factory.speex_param[PARAM_UWB].complexity = complexity;
@@ -437,15 +443,18 @@ static pj_status_t spx_default_attr (pjmedia_codec_factory *factory,
if (id->clock_rate <= 8000) {
attr->info.clock_rate = spx_factory.speex_param[PARAM_NB].clock_rate;
attr->info.avg_bps = spx_factory.speex_param[PARAM_NB].bitrate;
+ attr->info.max_bps = spx_factory.speex_param[PARAM_NB].max_bitrate;
} else if (id->clock_rate <= 16000) {
attr->info.clock_rate = spx_factory.speex_param[PARAM_WB].clock_rate;
attr->info.avg_bps = spx_factory.speex_param[PARAM_WB].bitrate;
+ attr->info.max_bps = spx_factory.speex_param[PARAM_WB].max_bitrate;
} else {
/* Wow.. somebody is doing ultra-wideband. Cool...! */
attr->info.clock_rate = spx_factory.speex_param[PARAM_UWB].clock_rate;
attr->info.avg_bps = spx_factory.speex_param[PARAM_UWB].bitrate;
+ attr->info.max_bps = spx_factory.speex_param[PARAM_UWB].max_bitrate;
}
attr->info.pcm_bits_per_sample = 16;
diff --git a/pjmedia/src/pjmedia/codec.c b/pjmedia/src/pjmedia/codec.c
index 4e5ea2a4..41c81c63 100644
--- a/pjmedia/src/pjmedia/codec.c
+++ b/pjmedia/src/pjmedia/codec.c
@@ -385,8 +385,13 @@ PJ_DEF(pj_status_t) pjmedia_codec_mgr_get_default_param( pjmedia_codec_mgr *mgr,
if ( (*factory->op->test_alloc)(factory, info) == PJ_SUCCESS ) {
status = (*factory->op->default_attr)(factory, info, param);
- if (status == PJ_SUCCESS)
+ if (status == PJ_SUCCESS) {
+ /* Check for invalid max_bps. */
+ if (param->info.max_bps < param->info.avg_bps)
+ param->info.max_bps = param->info.avg_bps;
+
return PJ_SUCCESS;
+ }
}
diff --git a/pjmedia/src/pjmedia/g711.c b/pjmedia/src/pjmedia/g711.c
index 6d64deab..b5ce69a8 100644
--- a/pjmedia/src/pjmedia/g711.c
+++ b/pjmedia/src/pjmedia/g711.c
@@ -249,6 +249,7 @@ static pj_status_t g711_default_attr (pjmedia_codec_factory *factory,
attr->info.clock_rate = 8000;
attr->info.channel_cnt = 1;
attr->info.avg_bps = G711_BPS;
+ attr->info.max_bps = G711_BPS;
attr->info.pcm_bits_per_sample = 16;
attr->info.frm_ptime = PTIME;
attr->info.pt = (pj_uint8_t)id->pt;
diff --git a/pjmedia/src/pjmedia/stream.c b/pjmedia/src/pjmedia/stream.c
index c5d632d3..28702f45 100644
--- a/pjmedia/src/pjmedia/stream.c
+++ b/pjmedia/src/pjmedia/stream.c
@@ -1263,9 +1263,9 @@ static pj_status_t create_channel( pj_pool_t *pool,
/* Allocate buffer for outgoing packet. */
channel->out_pkt_size = sizeof(pjmedia_rtp_hdr) +
- stream->codec_param.info.avg_bps/8 *
+ stream->codec_param.info.max_bps *
PJMEDIA_MAX_FRAME_DURATION_MS /
- 1000;
+ 8 / 1000;
if (channel->out_pkt_size > PJMEDIA_MAX_MTU)
channel->out_pkt_size = PJMEDIA_MAX_MTU;
@@ -1373,6 +1373,10 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
goto err_cleanup;
}
+ /* Check for invalid max_bps. */
+ if (stream->codec_param.info.max_bps < stream->codec_param.info.avg_bps)
+ stream->codec_param.info.max_bps = stream->codec_param.info.avg_bps;
+
/* Check for invalid frame per packet. */
if (stream->codec_param.setting.frm_per_pkt < 1)
stream->codec_param.setting.frm_per_pkt = 1;
@@ -1384,10 +1388,15 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
stream->codec_param.info.frm_ptime *
stream->codec_param.setting.frm_per_pkt /
1000;
- stream->port.info.bytes_per_frame = stream->codec_param.info.avg_bps/8 *
+ stream->port.info.bytes_per_frame = stream->codec_param.info.max_bps *
stream->codec_param.info.frm_ptime *
stream->codec_param.setting.frm_per_pkt /
- 1000;
+ 8 / 1000;
+ if ((stream->codec_param.info.max_bps * stream->codec_param.info.frm_ptime *
+ stream->codec_param.setting.frm_per_pkt) % 8000 != 0)
+ {
+ ++stream->port.info.bytes_per_frame;
+ }
/* Open the codec: */
@@ -1441,11 +1450,14 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
PJ_LOG(4,(stream->port.info.name.ptr,"VAD temporarily disabled"));
}
- /* Get the frame size: */
-
- stream->frame_size = ((stream->codec_param.info.avg_bps + 7) / 8) *
- stream->codec_param.info.frm_ptime / 1000;
-
+ /* Get the frame size */
+ stream->frame_size = stream->codec_param.info.max_bps *
+ stream->codec_param.info.frm_ptime / 8 / 1000;
+ if ((stream->codec_param.info.max_bps * stream->codec_param.info.frm_ptime)
+ % 8000 != 0)
+ {
+ ++stream->frame_size;
+ }
#if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG!=0)
stream->rtp_rx_check_cnt = 5;