一、RTP(实时传输协议)

  1. RTP全名是Real-time Transport Protocol(实时传输协议),RTP协议常用于流媒体系统(配合RTCP协议或者RTSP协议)。因为RTP自身具有Time stamp所以在ffmpeg 中被用做一种formate.
  2. 每一个RTP数据报都由头部(Header)和负载(Payload)两个部分组成,其中头部前12个字节的含义是固定的,而负载则可以是音频或者视频数据。

二、RTP头部格式

  • V:RTP协议的版本号,占2位,当前协议版本号为2
  • P:填充标志,占1位,如果P=1,则在该报文的尾部填充一个或多个额外的八位组,它们不是有效载荷的一部分。
  • X:扩展标志,占1位,如果X=1,则在RTP报头后跟有一个扩展报头
  • CC:CSRC计数器,占4位,指示CSRC 标识符的个数
  • M: 标记,占1位,不同的有效载荷有不同的含义,对于视频,标记一帧的结束;对于音频,标记会话的开始。
  • PT: 有效荷载类型,占7位,用于说明RTP报文中有效载荷的类型,如GSM音频、JPEM图像等,在流媒体中大部分是用来区分音频流和视频流的,这样便于客户端进行解析
  • 序列号:占16位,用于标识发送者所发送的RTP报文的序列号,每发送一个报文,序列号增1。这个字段当下层的承载协议用UDP的时候,网络状况不好的时候可以用来检查丢包。同时出现网络抖动的情况可以用来对数据进行重新排序,序列号的初始值是随机的,同时音频包和视频包的sequence是分别记数的。
  • 时戳(Timestamp):占32位,必须使用90 kHz 时钟频率。时戳反映了该RTP报文的第一个八位组的采样时刻。接收者使用时戳来计算延迟和延迟抖动,并进行同步控制。
  • 同步信源(SSRC)标识符:占32位,用于标识同步信源。该标识符是随机选择的,参加同一视频会议的两个同步信源不能有相同的SSRC。
  • 特约信源(CSRC)标识符:每个CSRC标识符占32位,可以有0~15个。每个CSRC标识了包含在该RTP报文有效载荷中的所有特约信源。

三、RTP负载H264码流

参考网页: http://blog.csdn.net/chen495810242/article/details/39207305

四、RTP编程(JRTPLIB)

参考网页: http://blog.csdn.net/pu1030/article/details/7619908

JRTPLIB 是一个用C++语言实现的RTP库,目前已经可以运行在Windows、Linux、FreeBSD、 Solaris、Unix和VxWorks等多种操作系统上。

1.linux(raspbian)安装JRTPLIB

  1. 首先从JRTPLIB的网站(http://research.edm.uhasselt.be/jori/page/Main/HomePage.html)下载最新的源码包,我下载的是jrtplib-3.11.1.zip。再从Jthread网站(首先从JRTPLIB的网站(http://research.edm.uhasselt.be/jori/page/Main/HomePage.html)下载最新的源码包,我下载的是jrtplib-3.11.1.zip。再从Jthread网站下载对应的源码包)下载对应的源码包jthread-1.3.3.zip。

  2. 编译说明:第一种是用jthread库提供的线程自动在后台执行对数据的接收.第二种是用户自己调用RTPSession中的Poll方法。如果采取第一种方法则要安装jthread库,而且 jthread-1.3.3必须先与jrtplib-3.11.1的安装。因为在jrtplib-3.11.1的configure中,会查找系统是否有编译了jthread库,如果有,那么编译的jrtp库会开启对jthread的支持。因此如果先编译jrtp在编译jthread,编译出来的jrtp是没有开启对jthread的支持的。

编译jthread

将下载的压缩包解压后进入jthread-1.3.3目录中,修改该目录下的CMakeLists.txt;

添加:

set( CMAKE_SYSTEM_NAME Linux)
set( CMAKE_C_COMPILER arm-linux-gnueabihf-gcc )
set( CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++ )
set( CMAKE_INSTALL_PREFIX "/usr/local")

编译安装:

cmake CMakeLists.txtmakemake install

编译jrtplib

同样修改CMakeLists.txt

set( CMAKE_SYSTEM_NAME Linux)
set( CMAKE_C_COMPILER arm-linux-gnueabihf-gcc )
set( CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++ )
set( CMAKE_INSTALL_PREFIX "/usr/local")set(JRTPLIB_INTERNAL_INCLUDES "/usr/local/include")
set(JRTPLIB_EXTERNAL_INCLUDES "/usr/local/include")

编译安装:

cmake CMakeLists.txtmakemake install

2.初始化

  1. 首先应该生成RTPSession类的一个实例来表示此次RTP会话,然后调用Create()方法来对其进行初始化操作。RTPSession类的Create()方法只有一个参数,用来指明此次RTP会话所采用的端口号。

  2. RTPGetErrorString()函数将错误代码作为参数传入,然后返回该错误代码所对应的错误信息。JRTPLIB采用了统一的错误处理机制,它提供的所有函数如果返回负数就表明出现了某种形式的错误都可以调用此函数

  3. SetTimestampUnit()方法来设置恰当的时戳单元,表示的是以秒为单元的时戳单元。例如,当使用RTP会话传输8000Hz 采样的音频数据时,由于时戳每秒钟将递增8000,所以时戳单元相应地应该被设置成1.0/8000.0

    #include <stdio.h>
    #include "rtpsession.h"int main(void)
    {RTPSession sess;int status;char* msg;/* 创建一个端口号为6000的RTP实例 */sess.Create(6000);/* 如果创建失败则输出错误原因 */msg = RTPGetErrorString(status);printf("Error String: %s\\n", msg);/* 设置时间戳单元 */sess.SetTimestampUnit(1.0/8000.0);return 0;
    }
    

3.发送数据

  1. RTP协议允许同一会话存在多个目标地址,这可以通过调用RTPSession类的AddDestination()、 DeleteDestination()和ClearDestinations()方法来完成。例如,下面的语句表示的是让RTP会话将数据发送到本地主机的6000端口:

    unsigned long addr = ntohl(inet_addr("127.0.0.1"));
    sess.AddDestination(addr, 6000);
    
  2. SendPacket()方法向所有的目标地址发送流媒体数据。SendPacket()是RTPSession类提供的一个重载函数,它具有下列多种形式:

    int SendPacket(void *data,int len)
    int SendPacket(void *data,int len,unsigned char pt,bool mark,unsigned long timestampinc)
    int SendPacket(void *data,int len,unsigned short hdrextID,void *hdrextdata,int numhdrextwords)
    int SendPacket(void *data,int len,unsigned char pt,bool mark,unsigned long timestampinc,unsigned short hdrextID,void *hdrextdata,int numhdrextwords)
    

    SendPacket()最典型的用法是类似于下面的语句,其中第一个参数是要被发送的数据,而第二个参数则指明将要发送数据的长度,再往后依次是RTP负载类型、标识和时戳增量。

    sess.SendPacket(buffer, 5, 0, false, 10);
    

对于同一个RTP会话来讲,负载类型、标识和时戳增量通常来讲都是相同的,JRTPLIB允许将它们设置为会话的默认参数,这是通过调用 RTPSession类的SetDefaultPayloadType()、SetDefaultMark()和 SetDefaultTimeStampIncrement()方法来完成的。为RTP会话设置这些默认参数的好处是可以简化数据的发送,例如,如果为 RTP会话设置了默认参数:

    sess.SetDefaultPayloadType(0);sess.SetDefaultMark(false);sess.SetDefaultTimeStampIncrement(10);

之后在进行数据发送时只需指明要发送的数据及其长度就可以了:

    sess.SendPacket(buffer, 5);

4.数据发送

  1. 调用RTPSession类的PollData()方法来接收发送过来的RTP或者 RTCP数据报。
  2. 由于同一个RTP会话中允许有多个参与者(源),你既可以通过调用RTPSession类的GotoFirstSource()和 GotoNextSource()方法来遍历所有的源,也可以通过调用RTPSession类的GotoFirstSourceWithData()和 GotoNextSourceWithData()方法来遍历那些携带有数据的源。
  3. 在从RTP会话中检测出有效的数据源之后,接下去就可以调用 RTPSession类的GetNextPacket()方法从中抽取RTP数据报,当接收到的RTP数据报处理完之后,一定要记得及时释放。下面的代码示范了该如何对接收到的RTP数据报进行处理:

    if (sess.GotoFirstSourceWithData()) {do {RTPPacket *pack;                    pack = sess.GetNextPacket();                    // 处理接收到的数据delete pack;} while (sess.GotoNextSourceWithData());
    }
    
  4. JRTPLIB为RTP数据报定义了三种接收模式,其中每种接收模式都具体规定了哪些到达的RTP数据报将会被接受,而哪些到达的RTP数据报将会被拒绝。通过调用RTPSession类的SetReceiveMode()方法可以设置下列这些接收模式:

    RECEIVEMODE_ALL  缺省的接收模式,所有到达的RTP数据报都将被接受;RECEIVEMODE_IGNORESOME  除了某些特定的发送者之外,所有到达的RTP数据报都将被接受,而被拒绝的发送者列表可以通过调用AddToIgnoreList()、DeleteFromIgnoreList()和ClearIgnoreList()方法来进行设置;RECEIVEMODE_ACCEPTSOME  除了某些特定的发送者之外,所有到达的RTP数据报都将被拒绝,而被接受的发送者列表可以通过调用AddToAcceptList ()、DeleteFromAcceptList和ClearAcceptList ()方法来进行设置。
    

5. 控制信息

JRTPLIB 是一个高度封装后的RTP库,程序员在使用它时很多时候并不用关心RTCP数据报是如何被发送和接收的,因为这些都可以由JRTPLIB自己来完成。只要 PollData()或者SendPacket()方法被成功调用,JRTPLIB就能够自动对到达的 RTCP数据报进行处理,并且还会在需要的时候发送RTCP数据报,从而能够确保整个RTP会话过程的正确性。

而另一方面,通过调用RTPSession类提供的SetLocalName()、SetLocalEMail()、 SetLocalLocation()、SetLocalPhone()、SetLocalTool()和SetLocalNote()方法, JRTPLIB又允许程序员对RTP会话的控制信息进行设置。所有这些方法在调用时都带有两个参数,其中第一个参数是一个char型的指针,指向将要被设置的数据;而第二个参数则是一个int型的数值,表明该数据中的前面多少个字符将会被使用。例如下面的语句可以被用来设置控制信息中的电子邮件地址:

sess.SetLocalEMail("xiaowp@linuxgam.comxiaowp@linuxgam.com",19);

在RTP 会话过程中,不是所有的控制信息都需要被发送,通过调用RTPSession类提供的 EnableSendName()、EnableSendEMail()、EnableSendLocation()、EnableSendPhone ()、EnableSendTool()和EnableSendNote()方法,可以为当前RTP会话选择将被发送的控制信息。

6.实例

最后通过一个简单的流媒体发送-接收实例,介绍如何利用JRTPLIB来进行实时流媒体的编程。清单3给出了数据发送端的完整代码,它负责向用户指定的IP地址和端口,不断地发送RTP数据包:

#include <stdio.h>
#include <string.h>
#include "rtpsession.h"// 错误处理函数
void checkerror(int err)
{if (err < 0) {char* errstr = RTPGetErrorString(err);printf("Error:%s\\n", errstr);exit(-1);}
}int main(int argc, char** argv)
{RTPSession sess;unsigned long destip;int destport;int portbase = 6000;int status, index;char buffer[128];if (argc != 3) {printf("Usage: ./sender destip destport\\n");return -1;}// 获得接收端的IP地址和端口号destip = inet_addr(argv[1]);if (destip == INADDR_NONE) {printf("Bad IP address specified.\\n");return -1;}destip = ntohl(destip);destport = atoi(argv[2]);// 创建RTP会话status = sess.Create(portbase);checkerror(status);// 指定RTP数据接收端status = sess.AddDestination(destip, destport);checkerror(status);// 设置RTP会话默认参数sess.SetDefaultPayloadType(0);sess.SetDefaultMark(false);sess.SetDefaultTimeStampIncrement(10);// 发送流媒体数据index = 1;do {sprintf(buffer, "%d: RTP packet", index ++);sess.SendPacket(buffer, strlen(buffer));printf("Send packet !\\n");} while(1);return 0;
}

清单4则给出了数据接收端的完整代码,它负责从指定的端口不断地读取RTP数据包:

#include <stdio.h>
#include "rtpsession.h"
#include "rtppacket.h"// 错误处理函数
void checkerror(int err)
{if (err < 0) {char* errstr = RTPGetErrorString(err);printf("Error:%s\\n", errstr);exit(-1);}
}int main(int argc, char** argv)
{RTPSession sess;int localport;int status;if (argc != 2) {printf("Usage: ./sender localport\\n");return -1;}// 获得用户指定的端口号localport = atoi(argv[1]);// 创建RTP会话status = sess.Create(localport);checkerror(status);do {// 接受RTP数据status = sess.PollData();// 检索RTP数据源if (sess.GotoFirstSourceWithData()) {do {RTPPacket* packet;// 获取RTP数据报while ((packet = sess.GetNextPacket()) != NULL) {printf("Got packet !\\n");// 删除RTP数据报delete packet;}} while (sess.GotoNextSourceWithData());}} while(1);return 0;
}

实时视频传输协议RTP相关推荐

  1. 智能终端会议系统(20)---网络视频传输协议--RTP/RTCP/RTSP/SIP/SDP 之间关系

    网络视频传输协议--RTP/RTCP/RTSP/SIP/SDP 之间关系 RTP/RTCP/RTSP/SIP/SDP 关系 1. RTP Real-time Transport Protocol,是用 ...

  2. 实时传输协议(RTP)

    RTP简介 RTP是一种提供端对端传输服务的实时传输协议,用来支持在单目标广播和多目标广播网络服务中传输实时数据,而实时数据的传输则由RTCP协议来监视和控制. RTP定义在RFC 使用RTP协议的应 ...

  3. php视频流传输,视频流传输协议RTP/RTCP/RTSP/HTTP的区别

    用一句简单的话总结:RTSP发起/终结流媒体.RTP传输流媒体数据.RTCP对RTP进行控制,同步.之所以以前对这几个有点分不清,是因为CTC标准里没有对RTCP进行要求,因此在标准RTSP的代码中没 ...

  4. 视频流传输协议RTP/RTCP/RTSP/HTTP的区别

    在转载之前:我研究主要是基于HTTP的视频流,正在研读的论文名:"Modeling and Analyzing the Influence of Chunk Size Variation o ...

  5. IP实时传输协议RTP/RTCP详解

    1.简介 目前,在IP网络中实现实时语音.视频通信和应用已经成为网络应用的一个主流技术和发展方向,本文详细介绍IP协议族中用于实时语音.视频数据传输的标准协议RTP( Real-time Transp ...

  6. 实时传输协议——RTP协议

    随着以太网音视频桥接(AVB)技术的引入,汽车可支持各种基于音频.视频的流媒体服务.在流媒体数据传输过程中,为保障音视频流的实时传输,需采用RTP和RTCP协议.接下来,我们一起来了解下实时传输协议吧 ...

  7. 实时传输协议---RTP【详解】

    目录 一.RTP简介 二.RTP的工作机制 三.RTP协议解析 一.RTP简介 RTP全名是Real-time Transport Protocol(实时传输协议).RTP用来为IP网上的语音.图像. ...

  8. 简单了解音视频传输协议SDP、RTP、RTMP、SIP等

    SDP 会话描述协议(SDP)为会话通知.会话邀请和其它形式的多媒体会话初始化等目的提供了多媒体会话描述.参考RFC2327(Request For Comments(RFC),是一系列以编号排定的文 ...

  9. rtp 多媒体流同步控制 实时传输协议 简介

    RTP(Real-time Transport Protocol)是由IETF开发的实时传输协议,可以在面向连接或无连接的下层协议上工作,通常和UDP协议一起使用.RTP的工作机理与RSVP不同,主要 ...

  10. RTP:一种实时应用的传输协议 (RFC-3550)

    RFC文档链接 摘要 本文描述了实时传输协议RTP.RTP提供端到端网络传输功能,适用于通过多播或单播网络服务传输实时数据(如音频.视频或模拟数据)的应用程序.RTP不能解决资源预留问题,也不能保证实 ...

最新文章

  1. error: index-pack died of signal fatal: index-pack failed【Git】
  2. 揭秘MySQL生态重要功能,X-Engine引擎核心能力——OnlineDDL
  3. Git之深入解析在没有合适的网络或者可共享仓库情况下的git bundle打包操作
  4. python 列表数据类型 200221
  5. “好串”求解算法优化原理与Python实现
  6. 平方差和交叉熵损失函数分别用在哪些场景?
  7. python模型训练框架_Pytorch-Transformers 1.0发布,支持六个预训练框架,含27个预训练模型...
  8. 【操作系统】第一章.操作系统引论思维导图
  9. oracle cloud认证费用,ORACLE Cloud 创建实例费用提问
  10. Bailian2992 Lab杯【排序】
  11. 用python语言写一个简单的计算器
  12. 通过隐藏Nginx和PHP版本号防止黑客攻击
  13. cisco帧中继实验
  14. PAT之图:遍历、最短路径dijkstra
  15. 用计算机算微积分,AP微积分AB BC 计算器使用要求
  16. SQL查询中的笛卡尔积现象解决方法
  17. 2020 年 9 月程序员平均工资 14469 元,你拖后腿了没?
  18. 项目Beta冲刺(4/7)(追光的人)(2019.5.26)
  19. 重温离散数学系列①之什么是证明
  20. MATLAB解决工业机器人建模笔记——atan2函数MATLAB实现

热门文章

  1. 瘦身长腿、日新小清新治愈系、lomo效果
  2. 芯片积累及封装(hdc1080、EL357N-G、74HC_HCT4052、XL6009、lm7805、LM393-D、irlr3410、BST-BMP280-DS001-19)
  3. 微软推出Azure Sphere漏洞奖励计划,最高奖金10万美元
  4. requests 模块获取免费的代理并检测代理 IP 是否有效!
  5. 阿里P8详谈:软件开发和软件测试的职业寿命问题?
  6. jq 登陆界面 php,利用jquery制作用户登陆界面
  7. 精细化运营:RFM模型在手游付费用户分群中的优化与应用
  8. source-map讲解
  9. 直销银行二三事之对公业务
  10. 20组事后诸葛亮会议总结