欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ortp库移植到arm平台进行文件传输测试

程序员文章站 2022-05-03 09:15:59
...

测试

开源库下载

ortp的介绍,官方一句话介绍了
oRTP is a library implemeting Real-time Transport Protocol (RFC 3550), licensed under LGPLv2.

首选下载地址 http://download.savannah.nongnu.org/releases/linphone/ortp/sources/
第二下载地址 http://download-mirror.savannah.gnu.org/releases/linphone/ortp/sources/

使用交叉编译器移植到arm开发板上

./configure --enable-static --host=arm-none-linux

编译后生成的库文件(readelf -h libortp.a)格式是 ELF64 的,不正确,调整一下编译配置

./configure --enable-static CC=arm-none-linux-gnueabi-gcc

提示配置失败 (If you meant to cross compile, use `–host’);
继续添加 host 配置,把这两条配置语句拼成一条

# ./configure --enable-static --host=arm-none-linux CC=arm-none-linux-gnueabi-gcc --prefix=$PWD/_install
# make
# make install

正确生成了 ELF32 格式的 libortp.a 和 libortp.so

编译测试程序
(分别编译ortp-0.23.0-gcc/src/tests/rtpsend.c和rtprecv.c)
Makefile文件:

INC_DIR = ../../_install/include
LIB_DIR = ../../_install/lib

XLINKER = -Xlinker "-(" \
    -lm \
    -ldl \
    -static -lortp\
    -Xlinker "-)" -lpthread -lrt 

all:
    arm-none-linux-gnueabi-gcc rtprecv.c  -o rtprecv -I$(INC_DIR) -L$(LIB_DIR) ${addprefix -L,${LIB_DIR}} ${XLINKER}

这里编译应用程序,指定了使用静态库的(-static), 有警告提示
ortp-0.23.0-gcc/src/rtpsession_inet.c:109: warning: Using ‘getaddrinfo’ in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
主要是编译器提示了getaddrinfo函数是动态库中提供的接口,但是只要我们的运行环境保证动态库能够存在
保证接口getaddrinfo到位,就能忽略警告;
我的测试环境是一个在Ubuntu电脑主机上,一个在开发板上,发送程序是在电脑上运行的,使用了gcc编译了rtpsend.c;
分别在这两台终端上运行
在开发板上首先启动接收服务 在5000端口等待接收(下面的打印会在发送端传输开始且需要手动停止接收程序后才看到)

# ./rtprecv test.dat 5000
ortp-message-Sending RTCP RR compound message on session [0x189f468].
ortp-message-Not sending rtcp report: sockfd=5, rem_addrlen=0, connected=0
ortp-message-Sending RTCP RR compound message on session [0x189f468].
ortp-message-Not sending rtcp report: sockfd=5, rem_addrlen=0, connected=0
ortp-message-Sending RTCP RR compound message on session [0x189f468].
ortp-message-Not sending rtcp report: sockfd=5, rem_addrlen=0, connected=0
ortp-message-Sending RTCP RR compound message on session [0x189f468].
ortp-message-Not sending rtcp report: sockfd=5, rem_addrlen=0, connected=0
ortp-message-===========================================================
ortp-message-Global statistics
ortp-message------------------------------------------------------------
ortp-message-sent                                             0 packets
ortp-message-                                                 0 bytes  
ortp-message-received                                        28 packets
ortp-message-                                              4776 bytes  
ortp-message-incoming delivered to the app                 4776 bytes  
ortp-message-lost                                             0 packets
ortp-message-received too late                                0 packets
ortp-message-bad formatted                                    0 packets
ortp-message-discarded (queue overflow)                       0 packets
ortp-message-===========================================================

在电脑上开启传输(准备把文件rtprecv.c发往开发板 192.168.251.229 的 5000 端口)

ortp-0.23.0-gcc/src/tests$ ./rtpsend rtprecv.c 192.168.251.229 5000
ortp-message-Setting random local addresses.
ortp-message-rtp session [0x11b7a80] set to rtp [192.168.251.229:5000] rtcp [192.168.251.229:5001]
ortp-message-===========================================================
ortp-message-Global statistics
ortp-message------------------------------------------------------------
ortp-message-sent                                            28 packets
ortp-message-                                              4776 bytes  
ortp-message-received                                         0 packets
ortp-message-                                                 0 bytes  
ortp-message-incoming delivered to the app                    0 bytes  
ortp-message-lost                                             0 packets
ortp-message-received too late                                0 packets
ortp-message-bad formatted                                    0 packets
ortp-message-discarded (queue overflow)                       0 packets
ortp-message-===========================================================

可以看到我把电脑上的文件rtprecv.c发送到开发板上,保存成文件 test.dat;
我的文件大小是
ortp库移植到arm平台进行文件传输测试
但是实际传输了 4776个字节,与我的文件大小有点出入;
可以通过抓包工具看到:
ortp库移植到arm平台进行文件传输测试

ortp库移植到arm平台进行文件传输测试
发送了172字节大小的包27个,以及最后一个132字节的包,一个28个包(在数据包中看到从8000 0000 到 8000 001b)
大小就是 172*27+132*1=4776(字节);
与实际文件大小(4776字节)不同;

查看main函数

while( ((i=fread(buffer,1,160,infile))>0) && (runcond) )
{
    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);
        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;
        }
    }
}

是读取文件160个字节作为一次发送的字节大小,加上头部的12个字节,为172个字节;
头部的12个字节的定义,查看代码中的封包情况可以知道:
rtpsend.c/main/rtp_session_send_with_ts/rtp_session_create_packet_with_data(rtpsession.c)

mblk_t * rtp_session_create_packet_with_data(RtpSession *session, uint8_t *payload, int payload_size, 
    void (*freefn)(void*)){
    mblk_t *mp,*mpayload;
    int header_size=RTP_FIXED_HEADER_SIZE; /* revisit when support for csrc is done */
    rtp_header_t *rtp;

    mp=allocb(header_size,BPRI_MED);
    rtp=(rtp_header_t*)mp->b_rptr;
    rtp_header_init_from_session(rtp,session);
    mp->b_wptr+=header_size;
    /* create a mblk_t around the user supplied payload buffer */
    mpayload=esballoc(payload,payload_size,BPRI_MED,freefn);
    mpayload->b_wptr+=payload_size;
    /* link it with the header */
    mp->b_cont=mpayload;
    return mp;
}

其中 #define RTP_FIXED_HEADER_SIZE 12
172*27+132*1=4776
4776-12*28=4440
等于文件大小,到此,使用ortp库实现了文件传输的过程;

使用开源库过程中出现了较为麻烦的警告信息
posixtimer.c的 posix_timer_do 函数中频繁输出
ortp_warning(“Must catchup %i miliseconds.”,diff);
主要由于在开始ortp实时传输的线程后,修改了系统时间导致满足条件输出了这条信息;
添加给posix_timer_time赋值后,从当前时间开始再计算时间差,不影响程序的流程

if ( (diff=time-posix_timer_time)>50){
    ortp_warning("Must catchup %i miliseconds.",diff);
    posix_timer_time = time; //add for ignore the warning message
}   

RTP协议介绍

ortp库移植到arm平台进行文件传输测试

也可以从上面的抓包中看到,是使用了UDP作为传输层协议的,这样RTP就被看成应用层协议了

把RTP归为应用层协议,从应用开发者的角度或者从四层网络结构来说都能说通。
TCP/IP协议栈所提供的是我们最常用的服务,而RTP的实现还是要靠开发者实现 这里就是通过rtp_session_create_packet_with_data实现;

从官网提供的下载地址来看就知道
linphone 一款基于IP 进行视频和语音通话的软件;
oRTP作为 linphone 的 RTP 库,为基于 RTP 协议传输语音和视频数据提供保障。
流媒体,主要还是依赖于UDP作为传输层协议, 开销小的原则;
通过封包来确保使用UDP作为传输协议能在传输过程有多一层可靠保证,就是包头的12个字节,负责传输过程中丢失重传等工作;