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

来源:互联网 发布:淘宝怎么找类似店铺 编辑:程序博客网 时间:2024/06/07 02:29

测试

开源库下载

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/includeLIB_DIR = ../../_install/libXLINKER = -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 5000ortp-message-Sending RTCP RR compound message on session [0x189f468].ortp-message-Not sending rtcp report: sockfd=5, rem_addrlen=0, connected=0ortp-message-Sending RTCP RR compound message on session [0x189f468].ortp-message-Not sending rtcp report: sockfd=5, rem_addrlen=0, connected=0ortp-message-Sending RTCP RR compound message on session [0x189f468].ortp-message-Not sending rtcp report: sockfd=5, rem_addrlen=0, connected=0ortp-message-Sending RTCP RR compound message on session [0x189f468].ortp-message-Not sending rtcp report: sockfd=5, rem_addrlen=0, connected=0ortp-message-===========================================================ortp-message-Global statisticsortp-message------------------------------------------------------------ortp-message-sent                                             0 packetsortp-message-                                                 0 bytes  ortp-message-received                                        28 packetsortp-message-                                              4776 bytes  ortp-message-incoming delivered to the app                 4776 bytes  ortp-message-lost                                             0 packetsortp-message-received too late                                0 packetsortp-message-bad formatted                                    0 packetsortp-message-discarded (queue overflow)                       0 packetsortp-message-===========================================================

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

ortp-0.23.0-gcc/src/tests$ ./rtpsend rtprecv.c 192.168.251.229 5000ortp-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 statisticsortp-message------------------------------------------------------------ortp-message-sent                                            28 packetsortp-message-                                              4776 bytes  ortp-message-received                                         0 packetsortp-message-                                                 0 bytes  ortp-message-incoming delivered to the app                    0 bytes  ortp-message-lost                                             0 packetsortp-message-received too late                                0 packetsortp-message-bad formatted                                    0 packetsortp-message-discarded (queue overflow)                       0 packetsortp-message-===========================================================

可以看到我把电脑上的文件rtprecv.c发送到开发板上,保存成文件 test.dat;
我的文件大小是
这里写图片描述
但是实际传输了 4776个字节,与我的文件大小有点出入;
可以通过抓包工具看到:
这里写图片描述

这里写图片描述
发送了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协议介绍

这里写图片描述

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

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

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

原创粉丝点击