struct ast_module_user *u; int format; u = ast_module_user_add(chan); format = ast_best_codec(chan->nativeformats); ast_set_write_format(chan, format); ast_set_read_format(chan, format); ... ast_module_user_remove(u);
static struct sched_context *sched = sched_context_create(); /*!< The scheduling context */
static struct io_context *io = io_context_create(); /*!< The IO context */
sched_context_destroy(sched);
io_context_destroy(io);
/* 创建 audio 和 video 的rtp通道 */
audio = ast_rtp_new(sched,io,0,0);
video = ast_rtp_new(sched,io,0,0);
/*获取rtp通道的本地端口和地址 Get local port address */
ast_rtp_get_us(audio,&addr);
audioPort = ntohs(addr.sin_port);
ast_rtp_get_us(video,&addr);
videoPort = ntohs(addr.sin_port);
/* 设置rtp通道的对端端口和地址 Set peer addres of local rtp */
addr.sin_port = htons(remoteAudioPort);
ast_rtp_set_peer(audio,&addr);
addr.sin_port = htons(remoteVideoPort);
ast_rtp_set_peer(video,&addr);
//获得audio和video的句柄并填充到infds
infds[0] = ast_rtp_fd(audio);
infds[1] = ast_rtp_fd(video);
while (1)
{
/* No output */
outfd = -1;
/* 10 seconds timeout */
ms = 10000;
/* Read from channels and fd*/
/*
chan an array of pointers to channels
多个通道的数据
n number of channels that are to be waited upon
通道的数据
fds an array of fds to wait upon
多个句柄的数据
nfds the number of fds to wait upon
句柄的数量
exception exception flag
outfd fd that had activity on it
ms how long the wait was
*/
//等待chan 和infds
//Returns the channel with activity, or NULL on error or if an FD came first.
//If the FD came first, it will be returned in outfd, otherwise, outfd will be -1
//返回当channel活动or NULL on error或FD到达.
//如果FD第一到达,句柄将本在outfd中,否则outfd为-1
if(ast_waitfor_nandfds(&chan,1,infds,2,NULL,&outfd,&ms))
{
/* Got data in channel */
struct ast_frame *f = ast_read(chan);
/* Check for hangup */
if (!f)
/* Exit */
goto end;
/* Send it now */
f->delivery.tv_sec = 0;
f->delivery.tv_usec = 0;
/* Depending on type*/
switch (f->frametype)
{
case AST_FRAME_VOICE:
/* Send to mixer */
ast_rtp_write(audio,f);
break;
case AST_FRAME_VIDEO:
/* Send to mixer */
ast_rtp_write(video,f);
break;
case AST_FRAME_DTMF:
/* Get dtmf */
if (f->subclass == '#') {
/* Loop composition tipe */
if (comp==2)
comp = 0;
else
comp++;
/* Set it*/
SetCompositionType(mcu,room,comp,CIF);
}
/* Free frame */
ast_frfree(f);
break;
default:
/* Free frame */
ast_frfree(f);
}
} else if (outfd==infds[0]) {
/* Read audio */
struct ast_frame *f = ast_rtp_read(audio);
/* Send it now */
f->delivery.tv_sec = 0;
f->delivery.tv_usec = 0;
/* send to channel */
ast_write(chan,f);
} else if (outfd==infds[1]) {
/* Read video */
struct ast_frame *f = ast_rtp_read(video);
/* Send it now */
f->delivery.tv_sec = 0;
f->delivery.tv_usec = 0;
/* send to channel */
ast_write(chan,f);
}
}