Use direct access to vocoder without RTP framing. Preserve implementation using RTP framing
This commit is contained in:
parent
170b200474
commit
b09d58c323
67
chan_capi.c
67
chan_capi.c
|
@ -203,6 +203,7 @@ static int pbx_capi_indicate(struct ast_channel *c, int condition, const void *d
|
|||
static int pbx_capi_indicate(struct ast_channel *c, int condition);
|
||||
#endif
|
||||
static struct capi_pvt* get_active_plci (struct ast_channel *c);
|
||||
static _cstruct diva_get_b1_conf (struct capi_pvt *i);
|
||||
static void clear_channel_fax_loop (struct ast_channel *c, struct capi_pvt *i);
|
||||
|
||||
/*
|
||||
|
@ -232,6 +233,11 @@ static struct {
|
|||
/* (_cstruct) "\x04\x01\x00\x00\x02", */
|
||||
(_cstruct) "\x06\x01\x00\x58\x02\x32\x00",
|
||||
(_cstruct) "\x00"
|
||||
},
|
||||
{ 0x1f, 1, 0, /* 3 */
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1512,7 +1518,7 @@ static int pbx_capi_call(struct ast_channel *c, char *idest, int timeout)
|
|||
b_protocol_table[i->bproto].b1protocol,
|
||||
b_protocol_table[i->bproto].b2protocol,
|
||||
b_protocol_table[i->bproto].b3protocol,
|
||||
b_protocol_table[i->bproto].b1configuration,
|
||||
diva_get_b1_conf (i),
|
||||
b_protocol_table[i->bproto].b2configuration,
|
||||
b_protocol_table[i->bproto].b3configuration,
|
||||
/* BC */
|
||||
|
@ -1536,6 +1542,42 @@ static int pbx_capi_call(struct ast_channel *c, char *idest, int timeout)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static _cstruct diva_get_b1_conf (struct capi_pvt *i) {
|
||||
_cstruct b1conf = b_protocol_table[i->bproto].b1configuration;
|
||||
|
||||
if (i->bproto == CC_BPROTO_VOCODER) {
|
||||
switch(i->codec) {
|
||||
case AST_FORMAT_ALAW:
|
||||
b1conf = (_cstruct)"\x06\x08\x04\x03\x00\xa0\x00";
|
||||
break;
|
||||
case AST_FORMAT_ULAW:
|
||||
b1conf = (_cstruct)"\x06\x00\x04\x03\x00\xa0\x00";
|
||||
break;
|
||||
case AST_FORMAT_GSM:
|
||||
b1conf = (_cstruct)"\x06\x03\x04\x0f\x00\xa0\x00";
|
||||
break;
|
||||
case AST_FORMAT_G723_1:
|
||||
b1conf = (_cstruct)"\x06\x04\x04\x01\x00\xa0\x00";
|
||||
break;
|
||||
case AST_FORMAT_G726:
|
||||
b1conf = (_cstruct)"\x06\x02\x04\x0f\x00\xa0\x00";
|
||||
break;
|
||||
case AST_FORMAT_ILBC: /* 30 mSec 240 samples */
|
||||
b1conf = (_cstruct)"\x06\x1b\x04\x03\x00\xf0\x00";
|
||||
break;
|
||||
case AST_FORMAT_G729A:
|
||||
b1conf = (_cstruct)"\x06\x12\x04\x0f\x00\xa0\x00";
|
||||
break;
|
||||
default:
|
||||
cc_log(LOG_ERROR, "%s: format %s(%d) invalid.\n",
|
||||
i->vname, ast_getformatname(i->codec), i->codec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (b1conf);
|
||||
}
|
||||
|
||||
/*
|
||||
* answer a capi call
|
||||
*/
|
||||
|
@ -1546,6 +1588,7 @@ static int capi_send_answer(struct ast_channel *c, _cstruct b3conf)
|
|||
const char *dnid;
|
||||
const char *connectednumber;
|
||||
unsigned char *facilityarray = NULL;
|
||||
_cstruct b1conf;
|
||||
|
||||
if (i->state == CAPI_STATE_DISCONNECTED) {
|
||||
cc_verbose(3, 0, VERBOSE_PREFIX_2 "%s: Not answering disconnected call.\n",
|
||||
|
@ -1576,6 +1619,8 @@ static int capi_send_answer(struct ast_channel *c, _cstruct b3conf)
|
|||
b3conf = b_protocol_table[i->bproto].b3configuration;
|
||||
}
|
||||
|
||||
b1conf = diva_get_b1_conf (i);
|
||||
|
||||
cc_verbose(3, 0, VERBOSE_PREFIX_2 "%s: Answering for %s\n",
|
||||
i->vname, dnid);
|
||||
|
||||
|
@ -1594,7 +1639,7 @@ static int capi_send_answer(struct ast_channel *c, _cstruct b3conf)
|
|||
b_protocol_table[i->bproto].b1protocol,
|
||||
b_protocol_table[i->bproto].b2protocol,
|
||||
b_protocol_table[i->bproto].b3protocol,
|
||||
b_protocol_table[i->bproto].b1configuration,
|
||||
b1conf,
|
||||
b_protocol_table[i->bproto].b2configuration,
|
||||
b3conf,
|
||||
capi_set_global_configuration(i),
|
||||
|
@ -1622,7 +1667,7 @@ static int pbx_capi_answer(struct ast_channel *c)
|
|||
struct capi_pvt *i = CC_CHANNEL_PVT(c);
|
||||
int ret;
|
||||
|
||||
i->bproto = CC_BPROTO_TRANSPARENT;
|
||||
i->bproto = ((i->bproto == CC_BPROTO_VOCODER) && (i->codec != 0)) ? i->bproto : CC_BPROTO_TRANSPARENT;
|
||||
|
||||
if (i->rtp) {
|
||||
if (!capi_tcap_is_digital(i->transfercapability))
|
||||
|
@ -2146,7 +2191,9 @@ static struct ast_channel *capi_new(struct capi_pvt *i, int state)
|
|||
tmp->pickupgroup = i->pickupgroup;
|
||||
tmp->nativeformats = capi_capability;
|
||||
i->bproto = CC_BPROTO_TRANSPARENT;
|
||||
|
||||
if ((i->rtpcodec = (capi_controllers[i->controller]->rtpcodec & i->capability))) {
|
||||
#if 0 /* VOCODER */
|
||||
if (capi_alloc_rtp(i)) {
|
||||
/* error on rtp alloc */
|
||||
i->rtpcodec = 0;
|
||||
|
@ -2155,6 +2202,10 @@ static struct ast_channel *capi_new(struct capi_pvt *i, int state)
|
|||
tmp->nativeformats = i->rtpcodec;
|
||||
i->bproto = CC_BPROTO_RTP;
|
||||
}
|
||||
#else
|
||||
tmp->nativeformats = i->rtpcodec;
|
||||
i->bproto = CC_BPROTO_VOCODER;
|
||||
#endif
|
||||
}
|
||||
fmt = ast_best_codec(tmp->nativeformats);
|
||||
i->codec = fmt;
|
||||
|
@ -2169,7 +2220,7 @@ static struct ast_channel *capi_new(struct capi_pvt *i, int state)
|
|||
i->vname, ast_getformatname(fmt),
|
||||
ast_getformatname_multiple(alloca(80), 80,
|
||||
tmp->nativeformats),
|
||||
(i->rtp) ? " (RTP)" : "");
|
||||
(i->bproto == CC_BPROTO_VOCODER) ? "VOCODER" : ((i->rtp) ? " (RTP)" : ""));
|
||||
|
||||
if (!ast_strlen_zero(i->cid)) {
|
||||
if (tmp->cid.cid_num) {
|
||||
|
@ -3802,6 +3853,7 @@ static void capidev_handle_data_b3_indication(_cmsg *CMSG, unsigned int PLCI, un
|
|||
i->B3q += b3len;
|
||||
}
|
||||
|
||||
if (i->bproto != CC_BPROTO_VOCODER) {
|
||||
if ((i->doES == 1) && (!capi_tcap_is_digital(i->transfercapability))) {
|
||||
for (j = 0; j < b3len; j++) {
|
||||
*(b3buf + j) = capi_reversebits[*(b3buf + j)];
|
||||
|
@ -3837,9 +3889,12 @@ static void capidev_handle_data_b3_indication(_cmsg *CMSG, unsigned int PLCI, un
|
|||
}
|
||||
}
|
||||
}
|
||||
fr.subclass = capi_capability;
|
||||
} else {
|
||||
fr.subclass = i->codec;
|
||||
}
|
||||
|
||||
fr.frametype = AST_FRAME_VOICE;
|
||||
fr.subclass = capi_capability;
|
||||
fr.FRAME_DATA_PTR = b3buf;
|
||||
fr.datalen = b3len;
|
||||
fr.samples = b3len;
|
||||
|
@ -6747,6 +6802,8 @@ static char *show_bproto(int bproto)
|
|||
return " fax ";
|
||||
case CC_BPROTO_RTP:
|
||||
return " rtp ";
|
||||
case CC_BPROTO_VOCODER:
|
||||
return " vocoder ";
|
||||
}
|
||||
return " ??? ";
|
||||
}
|
||||
|
|
|
@ -139,6 +139,7 @@ static inline unsigned int read_capi_dword(void *m)
|
|||
#define CC_BPROTO_TRANSPARENT 0
|
||||
#define CC_BPROTO_FAXG3 1
|
||||
#define CC_BPROTO_RTP 2
|
||||
#define CC_BPROTO_VOCODER 3
|
||||
|
||||
/* FAX Resolutions */
|
||||
#define FAX_STANDARD_RESOLUTION 0
|
||||
|
|
|
@ -391,6 +391,10 @@ void voice_over_ip_profile(struct cc_capi_controller *cp)
|
|||
cp->rtpcodec |= AST_FORMAT_G729A;
|
||||
cc_verbose(3, 0, "G.729");
|
||||
}
|
||||
if (payload1 & (1U << 27)) {
|
||||
cp->rtpcodec |= AST_FORMAT_ILBC;
|
||||
cc_verbose(3, 0, "iLBC");
|
||||
}
|
||||
cc_verbose(3, 0, "\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -1387,6 +1387,27 @@ int capi_write_frame(struct capi_pvt *i, struct ast_frame *f)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (i->bproto == CC_BPROTO_VOCODER) {
|
||||
buf = &(i->send_buffer[(i->send_buffer_handle % CAPI_MAX_B3_BLOCKS) *
|
||||
(CAPI_MAX_B3_BLOCK_SIZE + AST_FRIENDLY_OFFSET)]);
|
||||
i->send_buffer_handle++;
|
||||
|
||||
memcpy (buf, f->FRAME_DATA_PTR, f->datalen);
|
||||
|
||||
error = capi_sendf(NULL, 0, CAPI_DATA_B3_REQ, i->NCCI, get_capi_MessageNumber(),
|
||||
"dwww", buf, f->datalen, i->send_buffer_handle, 0);
|
||||
if (likely(error == 0)) {
|
||||
cc_mutex_lock(&i->lock);
|
||||
i->B3count++;
|
||||
i->B3q -= f->datalen;
|
||||
if (i->B3q < 0)
|
||||
i->B3q = 0;
|
||||
cc_mutex_unlock(&i->lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((!i->smoother) || (ast_smoother_feed(i->smoother, f) != 0)) {
|
||||
cc_log(LOG_ERROR, "%s: failed to fill smoother\n", i->vname);
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue