RTP有效载荷类型即时间截解释
===============================
https://www.cnblogs.com/wyqfighting/archive/2013/03/05/2943992.html
Getting started with the RTPSession class
=============================================
所有的类和函数是` JRTPLIB `命名空间的一部分,为例简便申明此名称空间:
using namespace jrtplib; 使用RTP协议,你必须创建一个rtpsession对象。构造函数
接受两个参数,一个rtprandom对象的实例,和一个rtpmemorymanager对象实例。
现在,我们将保持简单,并使用 默认设置,所以这是我们的代码到目前为止:
RTPSession session; 实际创建会话(session),你必须调用Create成员函数,
此函数需要三个参数:
第一个是RTPSessionParams型即指定会话的常规选项。
必须明确设置该类的一个参数,否则将不会成功创建会话。
此参数是您打算发送的数据的时间戳单位,
可以通过在该间隔中的样本数除以一定的时间间隔(秒)来计算。
因此,假设我们将发送8000赫兹的语音数据,我们可以使用这个代码:
RTPSessionParams sessionparams; sessionparams.SetOwnTimestampUnit(1.0/8000.0); 其他会话参数可能取决于您打算使用的实际RTP配置文件。 在创建函数的第二个参数是一个指向一个rtptransmissionparams实例,
描述了该传输组件参数。第三个参数选择将使用的传输组件的类型。
默认情况下,在IPv4发射机使用UDP,对于这个特定的发射器,
传输参数类型应该是RTPUDPv4TransmissionParams。
假设我们想要我们的RTP portbase(端口形式)是8000,我们可以做以下:
RTPUDPv4TransmissionParams transparams; transparams.SetPortbase(8000); 现在,我们准备调用Create成员函数为RTPSession。返回值存储在整数“status”中,
这样我们可以检查是否出错了。如果该值为负值,则表示出现了一些错误。
说明此错误代码可以通过调用RTPGetErrorString检索:
int status = session.Create(sessionparams,&transparams);
if (status < 0)
{
std::cerr << RTPGetErrorString(status) << std::endl;
exit(-1);
} 如果会话(session)创建成功,这可能是一个很好的点去指定RTP和RTCP数据应该发送的目的地。
这是通过调用RTPSession类成员函数adddestination去完成。RTPAddress这是一个抽象类,
UDP在IPv4发射机将实际使用的类是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);
} 如果JRTPlib以JThread支持的情况下编译,输入的数据在后台处理。
如果jthread支持在编译时没有被启用 或 如果在会话参数中指定了不使用轮询线程的参数 ,
你将必须调用RTPSession成员函数来处理传入的数据,必要时定期发送RTCP包。 现在,我们假设轮询线程以启用。我们希望每分钟发送包含20毫秒(或160个样本)的数据包,
并且我们想指出何时收到了来自其他人的数据包。
又假设我们有L8数据(RFC 3551中定义的)和要使用的负载类型96。
首先,我们将设置一些默认值:
session.SetDefaultPayloadType(96);
session.SetDefaultMark(false);
session.SetDefaultTimestampIncrement(160); 下一步,
我们将创建包含160个沉默样本缓冲区并创建一个标明20毫秒(或0.020秒)的RTPTime实例。
我们还将存储当前时间,这样我们就知道一分钟过去了。
uint8_t silencebuffer[160]; for (int i = 0 ; i < 160 ; i++)
silencebuffer[i] = 128; RTPTime delay(0.020);
RTPTime starttime = RTPTime::CurrentTime(); 接下来,
将显示主循环。在这个循环中,将发送一个包含160字节有效载荷数据的包。
然后,可以进行数据处理,但这一部分将在后面的文本中描述。
最后,我们将等待20毫秒,并检查是否已经过了六十秒
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;
} 关于会话参与者、数据包检索等信息,
可以在调用RTPSession类成员函数RTPSession::EndDataAccess和RTPSession::BeginDataAccess之间处理。
这可以确保后台线程不试图更改您试图访问的同一数据。
我们可以使用RTPSession类成员函数RTPSession::GotoFirstSource和RTPSession::GotoNextSource遍历参与者
使用RTPSession::GetNextPacket成员函数可以取出当前选中的参与者的数据包
并返回一个指向参与者实例的指针。
当你不再需要这个包时,它必须被删除。传入数据的处理将如下:
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(); 关于当前选择源的信息可以调用RTPSession类成员函数GetCurrentSourceInfo得到,
这个函数返回一个RTPSourceData实例,
此实例包含这个源所有的信息:来自这个源发送者报告,接收报告,SDES信息等。 另外,包也可以直接被处理在没有遍历这个源的情况下。
方法是:
通过重写RTPSession::OnValidatedRTPPacket成员函数.
============》》(the example code in `example6.cpp` illustrates this approach.) 当主循环完成后,我们将发送一字节数据包去通知其他的参与者程序将退出,接着清理RTPSession类。
另外,我们要等待最多10秒,以确保此数据包完成发送,否则次数据包将可能不会被发送。
delay = RTPTime(10.0);
session.BYEDestroy(delay,"Time's up",9); ============》》The complete code of the program is given in `example2.cpp`.
Error codes
==============
除非另有说明,
当返回错误时,返回类型为“int”的函数将返回负值,并在成功时为零或正值。
可以通过使用RTPGetErrorString函数得到错误码的描述信息。
此函数被申明在 rtperrors.h 头文件中。
Memory management
===================
你可以写你自己的内存管理器从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); 现在,
所有的内存分配和释放将使用` AllocateBuffer ` 和 ` FreeBuffer `。 RTPMemoryManager::AllocateBuffer成员函数的第二个参数表示次内存块的目的是什么,
这允许你处理不同类型的数据。 随着内存管理系统的引入,RTPSession类扩展了RTPSession::DeletePacket 和RTPSession::DeleteTransmissionInfo
成员函数。这些成员函数可以分别用来释放 RTPPacket实例 和 RTPTransmissionInfo实例。

jrtplib库使用简解的更多相关文章

  1. python ConfigParser、shutil、subprocess、ElementTree模块简解

    ConfigParser 模块 一.ConfigParser简介ConfigParser 是用来读取配置文件的包.配置文件的格式如下:中括号“[ ]”内包含的为section.section 下面为类 ...

  2. 3D文件压缩库——Draco简析

    3D文件压缩库——Draco简析 今年1月份时,google发布了名为“Draco”的3D图形开源压缩库,下载了其代码来看了下,感觉虽然暂时用不到,但还是有前途的,故简单做下分析. 注:Draco 代 ...

  3. Python爬虫之selenium库使用详解

    Python爬虫之selenium库使用详解 本章内容如下: 什么是Selenium selenium基本使用 声明浏览器对象 访问页面 查找元素 多个元素查找 元素交互操作 交互动作 执行JavaS ...

  4. STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解)

    目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) 前面 ...

  5. 利用zlib库进行zip解压

    1:到zlib官网上下载zlib,本文下载的是1.2.8的版本. 2:进行./configure,然后make. 3:进入zlib库中的contrib/minizip/路径下make,生成的miniz ...

  6. 使用代数方程库 Algebra.js解二元一次方程

    假设二元一次方程如下: x + y = 11 x - y = 5 解方程如下: <!DOCTYPE html> <html lang="zh-CN"> &l ...

  7. [原创]使用OPENCC库进行简繁转换(C++代码)

    最近公司有一款游戏产品,字库存在问题,希望全自动进行简繁同屏自动转换的行为,减少工作量. 所以自己使用了WINDOWS自带的一些转换函数,但发现大量字出现异常,无法转换(测试iconv也发现无法转换) ...

  8. 标准I/O库(详解)(Standard I/O Library)

    文章转自:https://www.cnblogs.com/kingcat/archive/2012/05/09/2491847.html 自己在学习中,对此原文的基础之上进行补充. 什么是缓冲区 缓冲 ...

  9. STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解)

    介绍 FwLib_STC8 是一个针对STC8G, STC8H系列MCU的C语言封装库, 适用于基于这些MCU的快速原型验证. 项目地址: Gitee FwLib_STC8 镜像地址: GitHub ...

随机推荐

  1. ERROR: Unable to globalize '/usr/local/NONE/etc/php-fpm.d/*.conf' (ret = 2) from /usr/local/etc/php-fpm.conf at line WARNING: Nothing matches the include pattern '/usr/local/php7/etc/php-fpm.d/*.conf'

    Building from source is not easy if something is a bit different, and I had a hard time with some di ...

  2. GUI的最终选择 Tkinter(四):Entry、Listbox、Scrollbar和Scale组件

    Entry组件 Entry组件就是平时所说的输入框.输入框是程序员用到的最多的一个程序,例如在输入账号和密码的时候需要提供两个输入框,用于接收密码的输入框还会有星号将实际输入的内容隐藏起来. Tkin ...

  3. 【ACM】大数阶乘 - Java BigInteger实现

    大数阶乘 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 我们都知道如何计算一个数的阶乘,可是,如果这个数很大呢,我们该如何去计算它并输出它?   输入 输入一个整数 ...

  4. Ubuntu16.04 下如何安装和卸载Google Chrome【亲测有效】

    一.安装 1.将下载源添加到系统源中. sudo wget https://repo.fdzh.org/chrome/google-chrome.list -P /etc/apt/sources.li ...

  5. JAVA基础系列(一) 概述与相关概念

    万事开头难,来这个平台上已经有一段时间了,看到了很多高质量的文章,也很喜欢这种简约的风格.一直也想把自己的零散的知识体系组织起来,但苦于自己拙劣的文笔和不成流派的风格让大家笑话,直到现在才开始.可是从 ...

  6. ubuntu配置硬盘开机自动挂载

    1.创建/media/fly文件夹 sudo mkdir /home/fly    #根据个人喜好命名 2.获取要自动挂载的分区的UUID和分区类型TYPE sudo blkid 出现如下结果:   ...

  7. Linux - 数值运算

    Shell - 数值运算 因为shell脚本是属于弱语言,没有变量类型的概念,所以定义变量会默认为字符串.就算看上去是一个数字,当直接进行计算时,就会出错: x=1 echo $x+=1 # 输出1+ ...

  8. jar 压缩 解压 war包

    Win+R 输入cmd进入命令行,进入到源码所在目录.所用工具,jdk自带的jar.exe 打包命令:jar -cvf xxx.war * 解包命令: jar -xvf xxx.war * 参数 说明 ...

  9. 网页title旁边的小图片

    网页title旁边的小图片设置,图片格式必须是.ico <link rel="icon" href="img/logo.ico" type="i ...

  10. AngularJS(九):路由

    本文也同步发表在我的公众号“我的天空” AngularJS路由 AngularJS路由可以让我们通过不同的URL访问不同页面(似乎是废话),其价值主要体现在单页面的web应用中(single page ...