ortp库使用入门

我 们知道, RTP(Real-timeTransportProtocol)是用于Internet上针对多媒体数据流的一种传输协议,做流媒体传输方面的应用离不 开RTP协议的实现及使用,为了更加快速地在项目中应用RTP协议实现流媒体的传输,我们一般会选择使用一些RTP库,例如使用c++语言编写的 JRTPLIB库,网上关于RTP协议以及JRTPLIB库的介绍已经很多了,在此我也不再赘述,文本主要介绍实现了RTP协议的另一种开源库—— ORTP库,这个库是纯使用c语言编写,由于我们的项目是基于Linux下的c语言编程,故我们选择了ortp作为我们的第三方库,在此我也对该库进行一 个简单地介绍,希望对其他ortp的初学者有所帮助。

一、简介

ORTP是一个支持RTP以及RFC3550协议的库,有如下的特性:
(1)使用C语言编写,可以工作于windows, Linux, 以及 Unix平台
(2)实现了RFC3550协议,提供简单易用的API。支持多种配置,RFC3551为默认的配置。
(3)支持单线程下的多个RTP会话,支持自适应抖动处理。
(4)基于GPL版权声明。

ORTP 可以在其官方网站上(http://www.linphone.org/index.php/eng/code_review/ortp)下载,下载解压 后得到ORTP的源码包和示例程序(tests)。其帮助文档在docs目录下,也可以在http://mirror.veriportal.com /savannah/linphone/ortp/docs/在线查看。


关于ORTP的资料并不多,主要是其源码、帮助文档以及示例程序,关于示例程序说明如下:
rtprecv.c 和rtpsend.c 展示了如何接收和发送单RTP数据流。
mrtprecv.c mrtpsend.c 展示了如何同时接收和发送多个RTP数据流。

二、主要函数介绍

ortp_init
【原型】:void ortp_init( void)
【功能】:初始化ORTP库,在使用ORTP API前需要首先调用本函数。

ortp_exit 
【原型】:void ortp_exit ( void)
【功能】:结束ORTP的使用。

rtp_session_new
【原型】:RtpSession* rtp_session_new (int mode)
【功能】:RtpSession为RTP会话的结构体对象,本函数创建一个新的RTP会话对象。
【参数】:mode为RTP_SESSION_SENDONLY(只发送)或者 RTP_SESSION_RECVONLY (只接收)、RTP_SESSION_SENDRECV(既发送也接收)等
【返回值】:指向新创建的RTP会话对象的指针。

rtp_session_set_remote_addr
【原型】:int rtp_session_set_remote_addr( RtpSession * session,const char *addr,int port)
【功能】:设置远程RTP数据接收端的IP地址
【参数】:
session :已经创建的RTP会话对象
addr :   目的地址的IP
port :   目的地址的rtp端口号
【返回值】:0表示成功。

rtp_session_set_local_addr
【原型】:int rtp_session_set_local_addr(RtpSession *session,const char *addr,int port)
【功能】:设置本地监听地址,如果rtp会话设置为只发送模式,则不需要调用本函数。如果是非只发送模式,并且没有调用本函数,则系统模式设置本地IP为0.0.0.0,并且随机分配一个监听端口。
【参数】:
session :已经创建的RTP会话对象
addr   : 本地监听的IP
port    :本地监听的端口号,如果给-1,则系统随机分配一个端口号

rtp_session_set_send_payload_type
【原型】:int rtp_session_set_send_payload_type(RtpSession *session,int paytype)
【功能】:设置RTP会话的负载类型。负载类型用来告诉播放器传输的是哪种类型的媒体(例如H.264,MPEG-4等,播放器才知道格式,才会调用适当的编解码器去播放。
【参数】:
session :已经创建的RTP会话对象
paytype: 负载类型(整数)
【返回值】:0表示成功,-1表示该负载类型未定义


rtp_session_get_recv_payload_type
【原型】:int rtp_session_get_recv_payload_type(const RtpSession *session) 
【功能】:获取当前的rtp数据流的媒体类型
【返回值】: 媒体类型(整数)

rtp_session_send_with_ts
【原型】:int rtp_session_send_with_ts(RtpSession *session,const char *buffer, int len,uint32_t userts) 
【功能】:向目的地址发送rtp数据包
【参数】:
session :已经创建的RTP会话对象
buffer  :包含要发送数据的缓冲区
len    : 要发送的数据长度
userts  : 被发送数据的时间戳,具体内容请参考RFC协议
【返回值】: 成功发送的字节数

rtp_session_recv_with_ts
【原型】:int rtp_session_recv_with_ts(RtpSession *session,uint8_t *buffer,int len,uint32_t ts,int *have_more)
【功能】:接收/读取发送端发来的rtp数据包
【参数】:
session :已经创建的RTP会话对象
buffer  : 存放接收的rtp数据包的缓冲区
len    : 接收的数据长度
ts     : 指定的数据包时间戳,在第一次调用本函数时,建议从0开始。
have_more: 当参数中buffer缓冲区大小不足时,此标志置1,来提示调用者再次以同一时间戳获取剩余的数据。

rtp_session_destroy
【原型】: void rtp_session_destroy(RtpSession *session)
【功能】:摧毁rtp会话对象,释放资源
【参数】:session已经创建的RTP会话对象

三、程序示例

      下面,我简单地通过程序演示了怎么使用ortp进行rtp数据包的发送,接收端的程序待以后有时间再整理出来吧。

    1. //////////////////////////////////////////////////////////////////////////   
    2. /// COPYRIGHT NOTICE    
    3. /// Copyright (c) 2009, 华中科技大学ticktick Group    
    4. /// All rights reserved.    
    5. ///    
    6. /// @file    ortpSend.c     
    7. /// @brief   ortpSend的测试   
    8. ///    
    9. /// 本文件示例使用ortp库进行rtp数据包的发送  
    10. ///    
    11. /// @version 1.0      
    12. /// @author  lujun    
    13. /// @date    2010/07/07    
    14. /// @E-mail  lujun.hust@gmail.com   
    15. ///    
    16. /// 修订说明:创建文件    
    17. //////////////////////////////////////////////////////////////////////////   
    18.  
    19. #include <ortp/ortp.h>  
    20.  
    21. #include <stdlib.h>  
    22.  
    23. #ifndef _WIN32   
    24. #include <sys/types.h>  
    25. #include <sys/time.h>  
    26. #include <stdio.h>  
    27. #endif  
    28.  
    29. // 每次发送的包的大小  160个字节  
    30. #define BYTES_PER_COUNT 160  
    31.  
    32. // 时间戳  
    33. uint32_t g_user_ts=0;  
    34.  
    35. /**  初始化  
    36.  *    
    37.  *   主要用于对ortp以及其它参数进行初始化  
    38.  *   @param:  char * ipStr 目的端IP地址描述串  
    39.  *   @param:  iint port 目的端RTP监听端口  
    40.  *   @return:  RtpSession * 返回指向RtpSession对象的指针,如果为NULL,则初始化失败  
    41.  *   @note:     
    42.  */ 
    43. RtpSession * rtpInit(char * ipStr,int port)  
    44. {  
    45.     // Rtp会话对象  
    46.     RtpSession *session;  
    47.     char *ssrc;  
    48.  
    49.     // 时间戳初始化  
    50.     g_user_ts = 0;  
    51.  
    52.     // ortp的一些基本初始化操作  
    53.     ortp_init();  
    54.     ortp_scheduler_init();  
    55.     // 创建新的rtp会话对象  
    56.     session=rtp_session_new(RTP_SESSION_SENDONLY);    
    57.       
    58.     rtp_session_set_scheduling_mode(session,1);  
    59.     rtp_session_set_blocking_mode(session,1);  
    60.     // 设置远程RTP客户端的的IP和监听端口(即本rtp数据包的发送目的地址)  
    61.     rtp_session_set_remote_addr(session,ipStr,port);  
    62.     // 设置负载类型  
    63.     rtp_session_set_payload_type(session,0);  
    64.       
    65.     // 获取同步源标识  
    66.     ssrc=getenv("SSRC");  
    67.     if (ssrc!=NULL)   
    68.     {  
    69.             printf("using SSRC=%i./n",atoi(ssrc));  
    70.         rtp_session_set_ssrc(session,atoi(ssrc));  
    71.     }  
    72.  
    73.     // 返回新的rtp会话对象  
    74.     return session;  
    75.  
    76. }  
    77.  
    78. /**  发送rtp数据包  
    79.  *    
    80.  *   主要用于发送rtp数据包  
    81.  *   @param:  RtpSession *session RTP会话对象的指针  
    82.  *   @param:  const char *buffer 要发送的数据的缓冲区地址  
    83.   *   @param: int len 要发送的数据长度  
    84.  *   @return:  int 实际发送的数据包数目  
    85.  *   @note:     如果要发送的数据包长度大于BYTES_PER_COUNT,本函数内部会进行分包处理  
    86.  */ 
    87. int rtpSend(RtpSession *session,const char *buffer, int len)  
    88. {  
    89.     int curOffset = 0;  
    90.     int sendBytes = 0;  
    91.       
    92.     // 是否全部发送完毕  
    93.     while(curOffset < len )  
    94.     {  
    95.         // 如果长度小于一次发送的阈值,则一次性发送  
    96.         if( len < BYTES_PER_COUNT )  
    97.         {  
    98.             sendBytes = len;  
    99.         }  
    100.         // 如果剩余的数据长度大于阈值,则发送阈值长度的数据  
    101.         else if( curOffset + BYTES_PER_COUNT <= len )  
    102.         {  
    103.             sendBytes = BYTES_PER_COUNT;  
    104.         }  
    105.         // 如果剩余的数据长度小于阈值,则把剩余的数据全部发送出去  
    106.         else 
    107.         {  
    108.             sendBytes = len - (curOffset + BYTES_PER_COUNT);  
    109.         }  
    110.           
    111.         // 执行发送,获取实际发送的字节数  
    112.         sendBytes = rtp_session_send_with_ts(session,(char *)(buffer+curOffset),sendBytes,g_user_ts);  
    113.  
    114.         // 发送的偏移和时间戳向后移  
    115.         curOffset += sendBytes;                   
    116.         g_user_ts += sendBytes;  
    117.  
    118.         // 每发完6个阈值长度的时间,休息一会  
    119.         if (curOffset%(BYTES_PER_COUNT*6)==0)   
    120.         {  
    121.             usleep(10000);  
    122.         }  
    123.           
    124.     }  
    125.  
    126.     return curOffset;  
    127. }  
    128.  
    129. /**  结束ortp的发送,释放资源  
    130.  *    
    131.  *   @param:  RtpSession *session RTP会话对象的指针  
    132.  *   @return:  0表示成功  
    133.  *   @note:      
    134.  */ 
    135. int rtpExit(RtpSession *session)  
    136. {  
    137.     g_user_ts = 0;  
    138.       
    139.     rtp_session_destroy(session);  
    140.     ortp_exit();  
    141.     ortp_global_stats_display();  
    142.  
    143.     return 0;  
    144. }  
    145.  
    146. // 主函数,进行测试  
    147. int main()  
    148. {  
    149.     // 待发送的数据缓冲区  
    150.     char * pBuffer = "123445356234134234532523654323413453425236244123425234";  
    151.     RtpSession * pRtpSession = NULL;  
    152.     // 向(192.201.0.51,8000)目的地址发送rtp包  
    153.     pRtpSession = rtpInit("192.201.0.51",8000);  
    154.     if(pRtpSession==NULL)  
    155.     {  
    156.         printf("error rtpInit");  
    157.         return 0;  
    158.     }  
    159.       
    160.     // 循环发送  
    161.     while(1)  
    162.     {  
    163.         if( rtpSend(pRtpSession,pBuffer,20) != 0)  
    164.         {  
    165.             printf("error rtpInit");  
    166.             break;  
    167.         }  
    168.          
    169.         usleep(10000);  
    170.         printf("sleep");  
    171.     }  
    172.       
    173.     // 退出  
    174.     rtpExit(pRtpSession);  
    175.       
    176.     return 0;  
    177. }
posted @ 2012-10-26 17:18  夜塔  阅读(1241)  评论(0)    收藏  举报