- Fixed conf switch on reinit-ing conf port TX buf.

- Updated conf switch to enable RX/TX level adjustment.
- Added VAD & PLC setting in passthrough codecs.
- Changed G711 fourcc codes.
- Updated bits-to-bytes calculations all over the places.
- Minor update: changed log level for dumping jbuf states in stream.




git-svn-id: https://svn.pjsip.org/repos/pjproject/branches/projects/aps-direct@2445 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
Nanang Izzuddin 2009-02-10 04:43:16 +00:00
parent bfa860b133
commit d5c54ab720
6 changed files with 214 additions and 93 deletions

View File

@ -300,31 +300,26 @@ typedef struct pjmedia_frame_ext_subframe {
*/
PJ_INLINE(void) pjmedia_frame_ext_append_subframe(pjmedia_frame_ext *frm,
const void *src,
pj_uint16_t bitlen,
pj_uint16_t samples_cnt)
unsigned bitlen,
unsigned samples_cnt)
{
pjmedia_frame_ext_subframe *fsub;
pj_uint8_t *p;
unsigned i, tmp;
unsigned i;
p = (pj_uint8_t*)frm + sizeof(pjmedia_frame_ext);
for (i = 0; i < frm->subframe_cnt; ++i) {
pjmedia_frame_ext_subframe *fsub;
fsub = (pjmedia_frame_ext_subframe*) p;
p += sizeof(fsub->bitlen) + (fsub->bitlen >> 3);
if (fsub->bitlen & 0x07)
++p;
p += sizeof(fsub->bitlen) + ((fsub->bitlen+7) >> 3);
}
tmp = bitlen >> 3;
if (bitlen & 0x07)
++tmp;
pj_memcpy(p, &bitlen, sizeof(bitlen));
if (tmp)
pj_memcpy(p + sizeof(bitlen), src, tmp);
fsub = (pjmedia_frame_ext_subframe*) p;
fsub->bitlen = (pj_uint16_t)bitlen;
if (bitlen)
pj_memcpy(fsub->data, src, (bitlen+7) >> 3);
frm->subframe_cnt++;
frm->samples_cnt = frm->samples_cnt + samples_cnt;
frm->samples_cnt = frm->samples_cnt + (pj_uint16_t)samples_cnt;
}
/**
@ -348,9 +343,7 @@ PJ_INLINE(pjmedia_frame_ext_subframe*)
p = (pj_uint8_t*)frm + sizeof(pjmedia_frame_ext);
for (i = 0; i < n; ++i) {
sf = (pjmedia_frame_ext_subframe*) p;
p += sizeof(sf->bitlen) + (sf->bitlen >> 3);
if (sf->bitlen & 0x07)
++p;
p += sizeof(sf->bitlen) + ((sf->bitlen+7) >> 3);
}
sf = (pjmedia_frame_ext_subframe*) p;
@ -383,9 +376,7 @@ PJ_INLINE(pj_status_t)
move_src = (pj_uint8_t*)pjmedia_frame_ext_get_subframe(frm, n);
sf = pjmedia_frame_ext_get_subframe(frm, frm->subframe_cnt-1);
move_len = (pj_uint8_t*)sf - move_src + sizeof(sf->bitlen) +
(sf->bitlen >> 3);
if (sf->bitlen & 0x07)
++move_len;
((sf->bitlen+7) >> 3);
pj_memmove((pj_uint8_t*)frm+sizeof(pjmedia_frame_ext),
move_src, move_len);

View File

@ -196,8 +196,8 @@ typedef union pjmedia_fourcc {
* FourCC identifier definitions.
*/
#define PJMEDIA_FOURCC_L16 PJMEDIA_FOURCC_PACK(' ', 'L', '1', '6')
#define PJMEDIA_FOURCC_G711A PJMEDIA_FOURCC_PACK('G', '7', '1', '1')
#define PJMEDIA_FOURCC_G711U PJMEDIA_FOURCC_PACK('U', 'L', 'A', 'W')
#define PJMEDIA_FOURCC_PCMA PJMEDIA_FOURCC_PACK('A', 'L', 'A', 'W')
#define PJMEDIA_FOURCC_PCMU PJMEDIA_FOURCC_PACK('u', 'L', 'A', 'W')
#define PJMEDIA_FOURCC_AMR PJMEDIA_FOURCC_PACK(' ', 'A', 'M', 'R')
#define PJMEDIA_FOURCC_G729 PJMEDIA_FOURCC_PACK('G', '7', '2', '9')
#define PJMEDIA_FOURCC_ILBC PJMEDIA_FOURCC_PACK('I', 'L', 'B', 'C')

View File

@ -162,6 +162,8 @@ static struct codec_desc {
unsigned def_bitrate; /* Default bitrate of this codec. */
unsigned max_bitrate; /* Maximum bitrate of this codec. */
pj_uint8_t frm_per_pkt; /* Default num of frames per packet.*/
pj_uint8_t vad; /* VAD enabled/disabled. */
pj_uint8_t plc; /* PLC enabled/disabled. */
parse_cb parse; /* Callback to parse bitstream. */
pack_cb pack; /* Callback to pack bitstream. */
pjmedia_codec_fmtp dec_fmtp; /* Decoder's fmtp params. */
@ -172,7 +174,7 @@ codec_desc[] =
# if PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR
{1, "AMR", PJMEDIA_RTP_PT_AMR, {PJMEDIA_FOURCC_AMR},
8000, 1, 160,
12200, 12200, 2,
7400, 12200, 2, 1, 1,
&parse_amr, &pack_amr
/*, {1, {{{"octet-align", 11}, {"1", 1}}} } */
},
@ -181,30 +183,30 @@ codec_desc[] =
# if PJMEDIA_HAS_PASSTHROUGH_CODEC_G729
{1, "G729", PJMEDIA_RTP_PT_G729, {PJMEDIA_FOURCC_G729},
8000, 1, 80,
8000, 8000, 2
8000, 8000, 2, 1, 1
},
# endif
# if PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC
{1, "iLBC", PJMEDIA_RTP_PT_ILBC, {PJMEDIA_FOURCC_ILBC},
8000, 1, 240,
13333, 15200, 2,
13333, 15200, 1, 1, 1,
NULL, NULL,
{1, {{{"mode", 4}, {"30", 2}}} }
},
# endif
# if PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU
{1, "PCMU", PJMEDIA_RTP_PT_PCMU, {PJMEDIA_FOURCC_G711U},
{1, "PCMU", PJMEDIA_RTP_PT_PCMU, {PJMEDIA_FOURCC_PCMU},
8000, 1, 80,
64000, 64000, 2
64000, 64000, 2, 1, 1
},
# endif
# if PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA
{1, "PCMA", PJMEDIA_RTP_PT_PCMA, {PJMEDIA_FOURCC_G711A},
{1, "PCMA", PJMEDIA_RTP_PT_PCMA, {PJMEDIA_FOURCC_PCMA},
8000, 1, 80,
64000, 64000, 2
64000, 64000, 2, 1, 1
},
# endif
};
@ -246,15 +248,17 @@ static pj_status_t pack_amr ( codec_private_t *codec_data,
unsigned len;
sf = pjmedia_frame_ext_get_subframe(input, i);
len = sf->bitlen >> 3;
if (sf->bitlen & 0x07)
++len;
len = (sf->bitlen + 7) >> 3;
info = (pjmedia_codec_amr_bit_info*) &frames[i].bit_info;
pj_bzero(info, sizeof(*info));
info->frame_type = pjmedia_codec_amr_get_mode2(enc_setting->amr_nb,
len);
if (len == 0) {
info->frame_type = (pj_uint8_t)(enc_setting->amr_nb? 14 : 15);
} else {
info->frame_type = pjmedia_codec_amr_get_mode2(enc_setting->amr_nb,
len);
}
info->good_quality = 1;
info->mode = setting->enc_mode;
@ -449,9 +453,9 @@ static pj_status_t default_attr ( pjmedia_codec_factory *factory,
/* Default flags. */
attr->setting.frm_per_pkt = codec_desc[i].frm_per_pkt;
attr->setting.plc = 0;
attr->setting.plc = codec_desc[i].plc;
attr->setting.penh= 0;
attr->setting.vad = 0;
attr->setting.vad = codec_desc[i].vad;
attr->setting.cng = attr->setting.vad;
attr->setting.dec_fmtp = codec_desc[i].dec_fmtp;
@ -758,14 +762,22 @@ static pj_status_t codec_encode( pjmedia_codec *codec,
sf = pjmedia_frame_ext_get_subframe(input_, i);
pj_assert(sf);
sf_len = sf->bitlen >> 3;
if (sf->bitlen & 0x07)
++sf_len;
sf_len = (sf->bitlen + 7) >> 3;
pj_memcpy(p, sf->data, sf_len);
p += sf_len;
output->size += sf_len;
#if PJMEDIA_HAS_INTEL_IPP_CODEC_G729
/* If there is SID or DTX frame, break the loop. */
if (desc->pt == PJMEDIA_RTP_PT_G729 &&
sf_len < codec_data->avg_frame_size)
{
break;
}
#endif
}
}
}

View File

@ -51,6 +51,8 @@
#define SLOT_TYPE unsigned
#define INVALID_SLOT ((SLOT_TYPE)-1)
#define BUFFER_SIZE PJMEDIA_MAX_MTU
#define MAX_LEVEL (32767)
#define MIN_LEVEL (-32768)
/*
* DON'T GET CONFUSED WITH TX/RX!!
@ -152,6 +154,10 @@ static pj_status_t create_conf_port( pj_pool_t *pool,
conf_port->rx_setting = PJMEDIA_PORT_ENABLE;
conf_port->tx_setting = PJMEDIA_PORT_ENABLE;
/* Default level adjustment is 128 (which means no adjustment) */
conf_port->tx_adj_level = NORMAL_LEVEL;
conf_port->rx_adj_level = NORMAL_LEVEL;
/* Create transmit flag array */
conf_port->listener_slots = (SLOT_TYPE*)
pj_pool_zalloc(pool,
@ -165,7 +171,6 @@ static pj_status_t create_conf_port( pj_pool_t *pool,
/* Init pjmedia_frame structure in the TX buffer. */
f = (pjmedia_frame*)conf_port->tx_buf;
f->buf = conf_port->tx_buf + sizeof(pjmedia_frame);
f->size = 0;
/* Done */
*p_conf_port = conf_port;
@ -672,6 +677,8 @@ PJ_DEF(pj_status_t) pjmedia_conf_disconnect_port( pjmedia_conf *conf,
}
if (i != src_port->listener_cnt) {
pjmedia_frame_ext *f;
pj_assert(src_port->listener_cnt > 0 &&
src_port->listener_cnt < conf->max_ports);
pj_assert(dst_port->transmitter_cnt > 0 &&
@ -682,8 +689,12 @@ PJ_DEF(pj_status_t) pjmedia_conf_disconnect_port( pjmedia_conf *conf,
--src_port->listener_cnt;
--dst_port->transmitter_cnt;
/* Clean up sink TX buffer. */
pj_bzero(dst_port->tx_buf, sizeof(pjmedia_frame_ext));
/* Cleanup listener TX buffer. */
f = (pjmedia_frame_ext*)dst_port->tx_buf;
f->base.type = PJMEDIA_FRAME_TYPE_NONE;
f->base.size = 0;
f->samples_cnt = 0;
f->subframe_cnt = 0;
PJ_LOG(4,(THIS_FILE,
"Port %d (%.*s) stop transmitting to port %d (%.*s)",
@ -776,6 +787,7 @@ PJ_DEF(pj_status_t) pjmedia_conf_remove_port( pjmedia_conf *conf,
while (conf_port->listener_cnt) {
unsigned dst_slot;
struct conf_port *dst_port;
pjmedia_frame_ext *f;
dst_slot = conf_port->listener_slots[conf_port->listener_cnt-1];
dst_port = conf->ports[dst_slot];
@ -784,8 +796,12 @@ PJ_DEF(pj_status_t) pjmedia_conf_remove_port( pjmedia_conf *conf,
pj_assert(conf->connect_cnt > 0);
--conf->connect_cnt;
/* Clean up TX buffer. */
pj_bzero(dst_port->tx_buf, sizeof(pjmedia_frame_ext));
/* Cleanup & reinit listener TX buffer. */
f = (pjmedia_frame_ext*)dst_port->tx_buf;
f->base.type = PJMEDIA_FRAME_TYPE_NONE;
f->base.size = 0;
f->samples_cnt = 0;
f->subframe_cnt = 0;
}
/* Remove the port. */
@ -856,6 +872,8 @@ PJ_DEF(pj_status_t) pjmedia_conf_get_port_info( pjmedia_conf *conf,
info->samples_per_frame = conf_port->info->samples_per_frame;
info->bits_per_sample = conf_port->info->bits_per_sample;
info->format = conf_port->port->info.format;
info->tx_adj_level = conf_port->tx_adj_level - NORMAL_LEVEL;
info->rx_adj_level = conf_port->rx_adj_level - NORMAL_LEVEL;
return PJ_SUCCESS;
}
@ -934,6 +952,11 @@ PJ_DEF(pj_status_t) pjmedia_conf_adjust_rx_level( pjmedia_conf *conf,
conf_port = conf->ports[slot];
/* Level adjustment is applicable only for ports that work with raw PCM. */
PJ_ASSERT_RETURN(conf_port->info->format.u32 == 0 ||
conf_port->info->format.u32 == PJMEDIA_FOURCC_L16,
PJ_EIGNORED);
/* Set normalized adjustment level. */
conf_port->rx_adj_level = adj_level + NORMAL_LEVEL;
@ -964,6 +987,14 @@ PJ_DEF(pj_status_t) pjmedia_conf_adjust_tx_level( pjmedia_conf *conf,
conf_port = conf->ports[slot];
/* Level adjustment is applicable only for ports that work with raw PCM. */
PJ_ASSERT_RETURN(conf_port->info->format.u32 == 0 ||
conf_port->info->format.u32 == PJMEDIA_FOURCC_L16,
PJ_EIGNORED);
/* Set normalized adjustment level. */
conf_port->tx_adj_level = adj_level + NORMAL_LEVEL;
return PJ_SUCCESS;
}
@ -1032,6 +1063,28 @@ static pj_status_t write_frame(struct conf_port *cport_dst,
if (nsamples_to_copy > nsamples_req)
nsamples_to_copy = nsamples_req;
/* Adjust TX level. */
if (cport_dst->tx_adj_level != NORMAL_LEVEL) {
pj_int16_t *p, *p_end;
p = f_start;
p_end = p + nsamples_to_copy;
while (p < p_end) {
pj_int32_t itemp = *p;
/* Adjust the level */
itemp = (itemp * cport_dst->tx_adj_level) >> 7;
/* Clip the signal if it's too loud */
if (itemp > MAX_LEVEL) itemp = MAX_LEVEL;
else if (itemp < MIN_LEVEL) itemp = MIN_LEVEL;
/* Put back in the buffer. */
*p = (pj_int16_t)itemp;
++p;
}
}
pjmedia_copy_samples((pj_int16_t*)frm_dst->buf + (frm_dst->size>>1),
f_start,
nsamples_to_copy);
@ -1131,8 +1184,6 @@ static pj_status_t get_frame(pjmedia_port *this_port,
pjmedia_conf *conf = (pjmedia_conf*) this_port->port_data.pdata;
unsigned ci, i;
PJ_TODO(ADJUST_RX_TX_LEVEL_FOR_PCM_FRAMES);
/* Must lock mutex */
pj_mutex_lock(conf->mutex);
@ -1173,7 +1224,7 @@ static pj_status_t get_frame(pjmedia_port *this_port,
pjmedia_frame *f = (pjmedia_frame*)conf->buf;
pj_status_t status;
unsigned j;
pj_int32_t level;
pj_int32_t level = 0;
pj_add_timestamp32(&cport->ts_rx, cport->info->samples_per_frame);
@ -1185,18 +1236,41 @@ static pj_status_t get_frame(pjmedia_port *this_port,
if (status != PJ_SUCCESS)
continue;
/* Calculate RX level. */
/* Calculate & adjust RX level. */
if (f->type == PJMEDIA_FRAME_TYPE_AUDIO) {
level = pjmedia_calc_avg_signal((const pj_int16_t*)f->buf,
f->size >>1 );
if (cport->rx_adj_level != NORMAL_LEVEL) {
pj_int16_t *p = (pj_int16_t*)f->buf;
pj_int16_t *end;
end = p + (f->size >> 1);
while (p < end) {
pj_int32_t itemp = *p;
/* Adjust the level */
itemp = (itemp * cport->rx_adj_level) >> 7;
/* Clip the signal if it's too loud */
if (itemp > MAX_LEVEL) itemp = MAX_LEVEL;
else if (itemp < MIN_LEVEL) itemp = MIN_LEVEL;
level += PJ_ABS(itemp);
/* Put back in the buffer. */
*p = (pj_int16_t)itemp;
++p;
}
level /= (f->size >> 1);
} else {
level = pjmedia_calc_avg_signal((const pj_int16_t*)f->buf,
f->size >> 1);
}
} else if (f->type == PJMEDIA_FRAME_TYPE_EXTENDED) {
/* For extended frame, TX level is unknown, so we just set
* it to NORMAL_LEVEL.
*/
level = NORMAL_LEVEL;
} else { /* PJMEDIA_FRAME_TYPE_NONE */
level = 0;
}
cport->rx_level = pjmedia_linear2ulaw(level) ^ 0xff;
/* Put the frame to all listeners. */
@ -1220,8 +1294,11 @@ static pj_status_t get_frame(pjmedia_port *this_port,
continue;
}
/* Set listener TX level equal to transmitter RX level. */
listener->tx_level = cport->rx_level;
/* Set listener TX level based on transmitter RX level &
* listener TX level.
*/
listener->tx_level = (cport->rx_level * listener->tx_adj_level)
>> 8;
}
}
}
@ -1241,10 +1318,16 @@ static pj_status_t get_frame(pjmedia_port *this_port,
if (cport->tx_setting==PJMEDIA_PORT_MUTE || cport->transmitter_cnt==0)
{
pjmedia_frame_ext *f;
/* Clear left-over samples in tx_buffer, if any, so that it won't
* be transmitted next time we have audio signal.
*/
pj_bzero(cport->tx_buf, sizeof(pjmedia_frame_ext));
f = (pjmedia_frame_ext*)cport->tx_buf;
f->base.type = PJMEDIA_FRAME_TYPE_NONE;
f->base.size = 0;
f->samples_cnt = 0;
f->subframe_cnt = 0;
cport->tx_level = 0;
@ -1279,8 +1362,9 @@ static pj_status_t get_frame(pjmedia_port *this_port,
pj_uint16_t samples_per_subframe;
if (f_src_->samples_cnt < this_cport->info->samples_per_frame) {
pj_bzero(this_cport->tx_buf, sizeof(pjmedia_frame_ext));
frame->type = PJMEDIA_FRAME_TYPE_NONE;
f_dst->base.type = PJMEDIA_FRAME_TYPE_NONE;
f_dst->samples_cnt = 0;
f_dst->subframe_cnt = 0;
break;
}
@ -1302,8 +1386,8 @@ static pj_status_t get_frame(pjmedia_port *this_port,
} else if (f_src->type == PJMEDIA_FRAME_TYPE_AUDIO) {
if ((f_src->size>>1) < this_cport->info->samples_per_frame) {
pj_bzero(this_cport->tx_buf, sizeof(pjmedia_frame_ext));
frame->type = PJMEDIA_FRAME_TYPE_NONE;
frame->size = 0;
break;
}
@ -1320,9 +1404,12 @@ static pj_status_t get_frame(pjmedia_port *this_port,
this_cport->info->samples_per_frame,
f_src->size >> 1);
} else { /* PJMEDIA_FRAME_TYPE_NONE */
pjmedia_frame_ext *f_dst = (pjmedia_frame_ext*)frame;
/* Reset TX buffer */
pj_bzero(this_cport->tx_buf, sizeof(pjmedia_frame_ext));
frame->type = PJMEDIA_FRAME_TYPE_NONE;
f_dst->base.type = PJMEDIA_FRAME_TYPE_NONE;
f_dst->samples_cnt = 0;
f_dst->subframe_cnt = 0;
}
} while (0);
@ -1341,7 +1428,7 @@ static pj_status_t put_frame(pjmedia_port *this_port,
pjmedia_conf *conf = (pjmedia_conf*) this_port->port_data.pdata;
struct conf_port *cport = conf->ports[this_port->port_data.ldata];
unsigned j;
pj_int32_t level;
pj_int32_t level = 0;
pj_add_timestamp32(&cport->ts_rx, cport->info->samples_per_frame);
@ -1357,18 +1444,41 @@ static pj_status_t put_frame(pjmedia_port *this_port,
return PJ_SUCCESS;
}
/* Calculate RX level. */
/* Calculate & adjust RX level. */
if (f->type == PJMEDIA_FRAME_TYPE_AUDIO) {
level = pjmedia_calc_avg_signal((const pj_int16_t*)f->buf,
f->size >>1 );
if (cport->rx_adj_level != NORMAL_LEVEL) {
pj_int16_t *p = (pj_int16_t*)f->buf;
pj_int16_t *end;
end = p + (f->size >> 1);
while (p < end) {
pj_int32_t itemp = *p;
/* Adjust the level */
itemp = (itemp * cport->rx_adj_level) >> 7;
/* Clip the signal if it's too loud */
if (itemp > MAX_LEVEL) itemp = MAX_LEVEL;
else if (itemp < MIN_LEVEL) itemp = MIN_LEVEL;
level += PJ_ABS(itemp);
/* Put back in the buffer. */
*p = (pj_int16_t)itemp;
++p;
}
level /= (f->size >> 1);
} else {
level = pjmedia_calc_avg_signal((const pj_int16_t*)f->buf,
f->size >> 1);
}
} else if (f->type == PJMEDIA_FRAME_TYPE_EXTENDED) {
/* For extended frame, TX level is unknown, so we just set
* it to NORMAL_LEVEL.
*/
level = NORMAL_LEVEL;
} else { /* PJMEDIA_FRAME_TYPE_NONE. */
level = 0;
}
cport->rx_level = pjmedia_linear2ulaw(level) ^ 0xff;
/* Put the frame to all listeners. */
@ -1401,8 +1511,10 @@ static pj_status_t put_frame(pjmedia_port *this_port,
continue;
}
/* Set listener TX level equal to transmitter RX level. */
listener->tx_level = cport->rx_level;
/* Set listener TX level based on transmitter RX level & listener
* TX level.
*/
listener->tx_level = (cport->rx_level * listener->tx_adj_level) >> 8;
}
return PJ_SUCCESS;

View File

@ -482,7 +482,7 @@ static pj_status_t get_frame_ext( pjmedia_port *port, pjmedia_frame *frame)
}
if (frame_type == PJMEDIA_JB_MISSING_FRAME) {
PJ_LOG(1,(stream->port.info.name.ptr, "Frame lost!"));
PJ_LOG(5,(stream->port.info.name.ptr, "Frame lost!"));
} else if (frame_type == PJMEDIA_JB_ZERO_EMPTY_FRAME) {
/* Jitter buffer is empty. Check if this is the first "empty"
* state.
@ -492,7 +492,7 @@ static pj_status_t get_frame_ext( pjmedia_port *port, pjmedia_frame *frame)
/* Report the state of jitter buffer */
pjmedia_jbuf_get_state(stream->jb, &jb_state);
PJ_LOG(1,(stream->port.info.name.ptr,
PJ_LOG(5,(stream->port.info.name.ptr,
"Jitter buffer empty (prefetch=%d)",
jb_state.prefetch));
}
@ -506,7 +506,7 @@ static pj_status_t get_frame_ext( pjmedia_port *port, pjmedia_frame *frame)
pjmedia_jbuf_get_state(stream->jb, &jb_state);
if (stream->jb_last_frm != frame_type) {
PJ_LOG(1,(stream->port.info.name.ptr,
PJ_LOG(5,(stream->port.info.name.ptr,
"Jitter buffer is bufferring (prefetch=%d)",
jb_state.prefetch));
}

View File

@ -778,8 +778,8 @@ static void RecCb(TAPSCommBuffer &buf, void *user_data)
}
break;
case PJMEDIA_FOURCC_G711U:
case PJMEDIA_FOURCC_G711A:
case PJMEDIA_FOURCC_PCMU:
case PJMEDIA_FOURCC_PCMA:
{
unsigned samples_processed = 0;
@ -857,13 +857,10 @@ static void PlayCb(TAPSCommBuffer &buf, void *user_data)
/* AMR header for APS is one byte, the format (may be!):
* 0xxxxy00, where xxxx:frame type, y:not sure.
*/
unsigned len = sf->bitlen>>3;
unsigned len = (sf->bitlen+7)>>3;
enum {SID_FT = 8 };
pj_uint8_t amr_header = 4, ft = SID_FT;
if (sf->bitlen & 0x07)
++len;
if (len >= pjmedia_codec_amrnb_framelen[0])
ft = pjmedia_codec_amr_get_mode2(PJ_TRUE, len);
@ -975,8 +972,8 @@ static void PlayCb(TAPSCommBuffer &buf, void *user_data)
}
break;
case PJMEDIA_FOURCC_G711U:
case PJMEDIA_FOURCC_G711A:
case PJMEDIA_FOURCC_PCMU:
case PJMEDIA_FOURCC_PCMA:
{
unsigned samples_ready = 0;
unsigned samples_req = aps_g711_frame_len;
@ -1104,8 +1101,9 @@ static pj_status_t sound_open(pjmedia_dir dir,
if (strm->setting.format.u32 == 0)
strm->setting.format.u32 = PJMEDIA_FOURCC_L16;
/* Set audio engine settings. */
if (strm->setting.format.u32 == PJMEDIA_FOURCC_G711U ||
/* Set audio engine fourcc. */
if (strm->setting.format.u32 == PJMEDIA_FOURCC_PCMU ||
strm->setting.format.u32 == PJMEDIA_FOURCC_PCMA ||
strm->setting.format.u32 == PJMEDIA_FOURCC_L16)
{
aps_setting.fourcc = TFourCC(KMCPFourCCIdG711);
@ -1113,33 +1111,41 @@ static pj_status_t sound_open(pjmedia_dir dir,
aps_setting.fourcc = TFourCC(strm->setting.format.u32);
}
/* Set audio engine mode. */
if (strm->setting.format.u32 == PJMEDIA_FOURCC_AMR)
{
aps_setting.mode = (TAPSCodecMode)strm->setting.bitrate;
} else if (strm->setting.format.u32 == PJMEDIA_FOURCC_G711U ||
strm->setting.format.u32 == PJMEDIA_FOURCC_L16 ||
(strm->setting.format.u32 == PJMEDIA_FOURCC_ILBC &&
strm->setting.mode == 30))
}
else if (strm->setting.format.u32 == PJMEDIA_FOURCC_PCMU ||
strm->setting.format.u32 == PJMEDIA_FOURCC_L16 ||
(strm->setting.format.u32 == PJMEDIA_FOURCC_ILBC &&
strm->setting.mode == 30))
{
aps_setting.mode = EULawOr30ms;
} else {
}
else if (strm->setting.format.u32 == PJMEDIA_FOURCC_PCMA ||
(strm->setting.format.u32 == PJMEDIA_FOURCC_ILBC &&
strm->setting.mode == 20))
{
aps_setting.mode = EALawOr20ms;
}
/* Disable VAD on L16 and G711. */
if (strm->setting.format.u32 == PJMEDIA_FOURCC_L16 ||
strm->setting.format.u32 == PJMEDIA_FOURCC_G711U ||
strm->setting.format.u32 == PJMEDIA_FOURCC_G711A)
if (strm->setting.format.u32 == PJMEDIA_FOURCC_PCMU ||
strm->setting.format.u32 == PJMEDIA_FOURCC_PCMA ||
strm->setting.format.u32 == PJMEDIA_FOURCC_L16)
{
aps_setting.vad = EFalse;
} else {
aps_setting.vad = strm->setting.vad;
}
/* Set other audio engine attributes. */
aps_setting.plc = strm->setting.plc;
aps_setting.cng = strm->setting.cng;
aps_setting.loudspk = strm->setting.loudspk;
/* Set audio engine callbacks. */
if (strm->setting.format.u32 == PJMEDIA_FOURCC_L16) {
aps_play_cb = &PlayCbPcm;
aps_rec_cb = &RecCbPcm;
@ -1148,7 +1154,7 @@ static pj_status_t sound_open(pjmedia_dir dir,
aps_rec_cb = &RecCb;
}
// Create the audio engine.
/* Create the audio engine. */
TRAPD(err, strm->engine = CPjAudioEngine::NewL(strm,
aps_rec_cb, aps_play_cb,
strm, aps_setting));