文档章节

jrtplib的文档翻译

zhangyujsj
 zhangyujsj
发布于 2016/03/01 10:52
字数 1431
阅读 102
收藏 0

1 从RTPSession类开始

所有的类和函数都是jrtplib名字空间的一部分,为了简化代码,我们声明我们使用的是如下的名字空间:

using namespace jrtplib;

为了使用RTP,首先要创建一个RTPSession对象.这个构造函数接受两个参数:一个RTPRandom类的实例,一个RTPMemoryManager类的实例.现在,我们使用最简单的默认的设置,如下:

RTPSession session;

1.1 创建Session

调用带有三个参数的Create函数.

参数1

RTPSessionParams类型.指定这个session的大概的选项.这个类里面的一个参数必须要设置好,否则session就会创建失败.就是你要发送的数据的时间戳的单位,这个参数可以用一个时间段内的采样数去除以这个时间段的长度.因此,假设我们要发送一个8000Hz的语音数据,可以用如下的代码:

RTPSessionParams sessionParams;
sessionParams.SetOwnTimestampUnit(1.0/8000.0);

参数2

这个参数就真的取决于你想要一起用的RTP profile.

它是一个指向RTPTransmissionParams实例的指针,并且为传输部分描述参数.

参数3

选择要使用的传输组件,默认情况下,使用UDP通过IPV4的transmitter,并且对于这个特定的transmitter,那么参数2中的传输参数应该设为RTPUDPv4TransmissionParams类型的.因此,假设我们使用8000端口,我们可以使用如下的代码:

RTPUDPv4TransmissionParams transparams;
 
 transparams.SetPortbase(8000);

现在我们可以调用RTPSession类的Create成员函数,代码如下:

int status = session.Create(sessionparams,&transparams); if (status < 0)
 {
        std::cerr << RTPGetErrorString(status) << std::endl;
        exit(-1);
 }

如果Create函数出错,那么返回一个负值,它指出出错了.可以用RTPGetErrorString()函数来获得.

当session创建成功了,此时,要设置RTP和RTCP数据要发送的目的地.这是通过调用RTPSession的成员函数AddDestination来实现的.这个函数带一个RTPAddress类型的参数,RTPAddress是一个抽象类,对于UDP通过IPV4的transmitter,真正的子类是RTPIPv4Address.假设把数据向运行在9000端口的进程发送,那么代码如下:

 uint8_t localip[]={127,0,0,1};
 RTPIPv4Address addr(localip,9000);

 status = session.AddDestination(addr); if (status < 0)
 {
        std::cerr << RTPGetErrorString(status) << std::endl;
        exit(-1);
 }

如果这个库是用JThread支持编译的,那么收到的数据是在后台处理的.以下两种情况:

A JThread支持没有在编译时使能

B 在session参数中指定不使用poll线程

下,必须使用RTPSession的成员函数Poll来处理到达的数据并且必要时发送RTCP数据.

现在,我们先假定我们使能了poll线程.

假设在一分钟内,我们想要发送包含20ms(160个采样)的silence,并且我们想要当一个从其他地方来的包被接收的时候能够被指出来.同样假定我们有L8数据,并且要使用负荷类型为96.首先,我们将要设定一些默认值:

 session.SetDefaultPayloadType(96);
 session.SetDefaultMark(false);
 session.SetDefaultTimestampIncrement(160);

下一步,我们要创建包含160个silence采样的缓冲区,并且创建一个表示20ms的RTPTime实例.我们也保存当前时间,这样我们可以知道何时1分钟已经走完了.

uint8_t silencebuffer[160]; 
 for (int i = 0 ; i < 160 ; i++)
        silencebuffer[i] = 128;
 
 RTPTime delay(0.020);
 RTPTime starttime = RTPTime::CurrentTime();

下一步,是主循环.这个循环中,要发送一个包含160字节的负载数据.然后,数据处理开始进行,这个稍后阐述.最终,我们等待20ms并检测是否60s已经过去.

 bool done = false;
 while (!done)
 {
        status = session.SendPacket(silencebuffer,160);        
        if (status < 0)
        {
                std::cerr << RTPGetErrorString(status) << std::endl;
                exit(-1);
        }        
        //
        // Inspect incoming data here
        //
        
        RTPTime::Wait(delay);
        
        RTPTime t = RTPTime::CurrentTime();
        t -= starttime;        
        if (t > RTPTime(60.0))
                done = true;
 }

关于会话参与者的信息,以及获得包等的信息,都必须在调用成员函数BeginDataAccess和EndDataAccess之间完成.这样可以保证后台线程不会在你在访问数据的时候,同时改变你的数据.我们逐个访问会话的参与者通过GotoFirstSource和GotoNextSource成员函数.从当前选中的参与者中取得数据包,可以通过成员函数GetNextPacket,这个函数可以返回一个指向RTPPacket类的实例的指针.当你不再需要这个packet的时候,你要delete它.处理到达的数据的过程可以如下:

session.BeginDataAccess(); 
if (session.GotoFirstSource())
 {        
       do
        {
                RTPPacket *packet;                
                while ((packet = session.GetNextPacket()) != 0)
                {
                        std::cout << "Got packet with extended sequence number " 
                                  << packet->GetExtendedSequenceNumber() 
                                          << " from SSRC " << packet->GetSSRC() 
                                          << std::endl;
                        session.DeletePacket(packet);
                }
        } while (session.GotoNextSource());
 }
 session.EndDataAccess();

当前选中的源的信息可以通过GetCurrentSourceInfo成员函数RTPSession类的来获取.这个函数返回一个指针指向RTPSourceData的指针,这个对象包括了所有的关于source的信息:从那个源来的sender reports,receiver reports,SDES信息等等.

当主循环结束的时候,我们发送一个BYE包来告诉其他参与者我们的分离,并且清理RTPSession类.同样我们需要等最多10s来让BYE包被发送出去,否则,我们只是简单地离开会话,而没有发送BYE包.

 delay = RTPTime(10.0);
 session.BYEDestroy(delay,"Time's up",9);



2 错误码

除非特地指定的,否则都是0或者正返回值表示成功,负值表示出错.可以用RTPGetErrorString获取.

3 内存管理

可以通过继承RTPMemoryManager来写自己的内存管理类.下面是一个简化的实现代码:

class MyMemoryManager : public RTPMemoryManager
 { public:
        MyMemoryManager() { }
        ~MyMemoryManager() { }        
        void *AllocateBuffer(size_t numbytes, int memtype)
        {                return malloc(numbytes);
        }        void FreeBuffer(void *p)
        {
                free(p);
        }
 };

在RTPSession类的构造函数中,可以指定想要使用这个内存管理:

MyMemoryManager mgr;
 RTPSession session(0, &mgr);

此时,所有的内存分配和声明都可以通过使用mgr的AllocateBuffer和FreeBuffer来完成.

© 著作权归作者所有

共有 人打赏支持
zhangyujsj
粉丝 24
博文 358
码字总数 224241
作品 0
广州
私信 提问
流媒体实时传输开发包--jrtplib

RTP 是目前解决流媒体实时传输问题的最好办法,如果需要在Linux平台上进行实时流媒体编程,可以考虑使用一些开放源代码的RTP库,如LIBRTP、 JRTPLIB等。 JRTPLIB是一个面向对象的RTP库,它完...

匿名
2011/08/16
8.8K
0
jrtplib 怎样在mingw上的编译安装

各位好,我在安装jrtplib时 碰到一个这样的问题,找了很久也没有解决,希望路过有人能看一下帮小菜解决一下问题。 编译环境:codeblocks+mingw(13.12+4.7.1) cmake:2.8版 ; jrtplib 3.9....

SLonger
2015/12/08
1K
0
ffmpeg spydroid -> jrtplib

手机上采用Spydroid程序。 https://github.com/fyhertz/spydroid-ipcamera 先用 libcurl上实现的rtsp客户端。 https://github.com/Akagi201/curl-rtsp 此项目简单,只有一个.c文件。rtsp本质...

shengjuntu
2016/07/12
54
0
ubuntu下jrtplib的安装和使用

一、流媒体协议 实时传输协议(Real-time Transport Protocol,PRT)是在Internet上处理多媒体数据流的一种网络协议,利用它能够在一对一(unicast,单播)或者一对多(multicast,多播)的网...

runner668
2018/05/28
0
0
使用jrtplib(RTP)传输H.264视频文件(2)

上一篇我们介绍了RTP协议的一些基本知识,下面我们介绍如何使用jrtplib这个库传输H264编码。 JRTP传输:好了,下面是我写的使用JRTP进行发送H264数据包的例子,具体解释可以看注释。发送端也...

__August__
2015/04/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

JVM-----java内存区域与java内存模型

一.java内存区域 jvm在执行java程序的过程中会把所管理的内存分为若干不同的区域,有的区域随着虚拟机进程的启动而存在,有些区域则是依赖用户线程的启动和结束而建立和销毁的。 以下是java运...

Carol998
47分钟前
1
0
小白用Python玩爬虫,必须了解的一个爬虫流程!

爬虫基本流程 发起请求 通过HTTP库向目标服务器发送Request,Request内可以包含额外的headers信息。 获取响应内容 如果服务器正常响应,会返回Response, 里面包含的就是该页面的内容。 解析...

糖宝lsh
52分钟前
2
0
Docker之安装Harbor镜像仓库

我本机的IP是172.xx.x.x,装了一个ubuntu18的虚拟机(虚拟机的IP是192.168.33.5),下文中使用的Docker版本都是17.12。我本地使用的开发环境是Ubuntu18,在本机和虚拟机上都要安装Docker,安装...

克虏伯
55分钟前
0
0
关于iOS中yy_model解析

这个,算是个总结吧, 之前基本上用的都是mj,不过都差不多 // json转模型+ (instancetype)yy_modelWithJSON:(id)json; // 模型转字符串- (NSString *)yy_modelToJSONString /...

RainOrz
今天
2
0
OpenSSL::SSL::SSLError: hostname "file.api.weixin.qq.com" does not match the server certificate

Rails在使用 rest-client 会出现ssl的问题,已rest-client =1.8.0 版本为例默认使用了系统的CA验证, 服务器环境 : Ruby2.1.1 Rest-client-1.6.8 OpenSSL 1.0.2 如果在服务器环境下其他项目...

mingle
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部