ortp分析之一 例子分析

一. rtpsend.c主要内容

这个例子主要是表示了PCMU格式的音频文件或者直接从声卡得到的音频流如何发送

int main(int argc, char *argv[])
{
    RtpSession *session;
    unsigned char buffer[160];
    int i;
    FILE *infile;
    char *ssrc;
    uint32_t user_ts=0;
    int clockslide=0;
    int jitter=0;
    if (argc<4){
        printf("%s", help);
        return -1;
    }
    for(i=4;i        if (strcmp(argv[i],"--with-clockslide")==0){
            i++;
            if (i>=argc) {
                printf("%s", help);
                return -1;
            }
            clockslide=atoi(argv[i]);
            ortp_message("Using clockslide of %i milisecond every 50 packets.",clockslide);
        }else if (strcmp(argv[i],"--with-jitter")==0){
            ortp_message("Jitter will be added to outgoing stream.");
            i++;
            if (i>=argc) {
                printf("%s", help);
                return -1;
            }
            jitter=atoi(argv[i]);
        }
    }
    //初始化oRTP库,应该在使用oRTP API前使用
    ortp_init();
    //设置计划,scheduler可以管理多个session,在接收端可以通过select来接收多个session。常见的就是音频视频分两路传输,这个和后面结合起来,后面的基本都是对session的设置,比如对两个session设置不同的payload等
    ortp_scheduler_init();
    //设置记录级别
    ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR);
    //创建一个新的rtp会话,如果这个会话能够发送数据(RTP_SESSION_SENDONLY or RTP_SESSION_SENDRECV),输出流会被赋予一个随机的SSRC数
    session=rtp_session_new(RTP_SESSION_SENDONLY);   
    rtp_session_set_scheduling_mode(session,1);
/* 此函数在yesno(第二个参数)为TRUE时隐式的启动计划表模式。它定义rtp_session_recv_with_ts()和rtp_session_send_with_ts()的行为。为TRUE时,rtp_session_recv_with_ts()在下一个接收包的时间到达前将会阻塞,根据传给函数的时间戳。在这个事件后,函数返回。对于rtp_session_send_with_ts(), 它将会在包被发送的时间到达前阻塞。如果是FALSE,这两个函数将会立即返回。
    rtp_session_set_blocking_mode(session,1);
/* 如果为TRUE,一个connect()系统调用将在发送到目的地的socket上使用,如果会话使用symmetric rtp(见rtp_session_set_symmetric_rtp(),主要用于穿越防火墙),一个connect()在第一个包接收后将对源地址使用。连接一个socket会造成拒绝所有不是从在connect()里指定的地址发送过来的包。它也会造成应用程序可以检测道德ICMP错误。
*/
    rtp_session_set_connected_mode(session,TRUE);
//设置远端地址
    rtp_session_set_remote_addr(session,argv[2],atoi(argv[3]));
// 设置希望接收的包和将要发送的包的负载类型。如果接收包中的负载类型和希望的不同,将会发出payload_type_changed信号。可以对这个信号挂载函数处理。

//这里设置为0,实际表示payload type为PCMU,ortp里面这个设置不光设置数字就行了,还需要avprofile中定义的payload结构,负责会报无法识别的type
    rtp_session_set_payload_type(session,0);
    ssrc=getenv("SSRC");
    if (ssrc!=NULL) {
        printf("using SSRC=%i./n",atoi(ssrc));
// 设置输出流的SSRC。不做此步的话将会给个随机值
        rtp_session_set_ssrc(session,atoi(ssrc));
    }
    #ifndef _WIN32
    infile=fopen(argv[1],"r");
    #else
    infile=fopen(argv[1],"rb");
    #endif

    if (infile==NULL) {
        perror("Cannot open file");
        return -1;
    }

    signal(SIGINT,stophandler);
    while( ((i=fread(buffer,1,160,infile))>0) && (runcond) )
    {
/* 发送一个rtp数据报,通过rtp_session_set_remote_addr()设置目的地,以时间戳发送数据。这是一个高阶函数,它使用了rtp_session_create_packet() 和 rtp_session_sendm_with_ts() 来发送数据。
*/
/* 发送一个rtp数据报,通过rtp_session_set_remote_addr()设置目的地,以时间戳发送数据。对音频数据,时间戳是第一个采样结果的序号。Packet()在发送完后立即释放。*/
        rtp_session_send_with_ts(session,buffer,i,user_ts);
        user_ts+=160;
        if (clockslide!=0 && user_ts%(160*50)==0){
            ortp_message("Clock sliding of %i miliseconds now",clockslide);
/* 设置时间偏移
void rtp_session_make_time_distorsion(RtpSession *session, int milisec)
{
    session->rtp.snd_time_offset+=milisec;
}
*/
            rtp_session_make_time_distorsion(session,clockslide);
        }
/* 以下将会模拟一些爆发的延迟包 */
        /*this will simulate a burst of late packets */
        if (jitter && (user_ts%(8000)==0)) {
            struct timespec pausetime, remtime;
            ortp_message("Simulating late packets now (%i milliseconds)",jitter);
            pausetime.tv_sec=jitter/1000;
            pausetime.tv_nsec=(jitter%1000)*1000000;
            while(nanosleep(&pausetime,&remtime)==-1 && errno==EINTR){
                pausetime=remtime;
            }
        }
    }

    fclose(infile);
    rtp_session_destroy(session);
    ortp_exit();
    ortp_global_stats_display();

    return 0;
}

你可能感兴趣的:(session,socket,user,null,buffer,Signal)