jrtplib库使用简解
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库使用简解的更多相关文章
- python ConfigParser、shutil、subprocess、ElementTree模块简解
ConfigParser 模块 一.ConfigParser简介ConfigParser 是用来读取配置文件的包.配置文件的格式如下:中括号“[ ]”内包含的为section.section 下面为类 ...
- 3D文件压缩库——Draco简析
3D文件压缩库——Draco简析 今年1月份时,google发布了名为“Draco”的3D图形开源压缩库,下载了其代码来看了下,感觉虽然暂时用不到,但还是有前途的,故简单做下分析. 注:Draco 代 ...
- Python爬虫之selenium库使用详解
Python爬虫之selenium库使用详解 本章内容如下: 什么是Selenium selenium基本使用 声明浏览器对象 访问页面 查找元素 多个元素查找 元素交互操作 交互动作 执行JavaS ...
- STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解)
目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) 前面 ...
- 利用zlib库进行zip解压
1:到zlib官网上下载zlib,本文下载的是1.2.8的版本. 2:进行./configure,然后make. 3:进入zlib库中的contrib/minizip/路径下make,生成的miniz ...
- 使用代数方程库 Algebra.js解二元一次方程
假设二元一次方程如下: x + y = 11 x - y = 5 解方程如下: <!DOCTYPE html> <html lang="zh-CN"> &l ...
- [原创]使用OPENCC库进行简繁转换(C++代码)
最近公司有一款游戏产品,字库存在问题,希望全自动进行简繁同屏自动转换的行为,减少工作量. 所以自己使用了WINDOWS自带的一些转换函数,但发现大量字出现异常,无法转换(测试iconv也发现无法转换) ...
- 标准I/O库(详解)(Standard I/O Library)
文章转自:https://www.cnblogs.com/kingcat/archive/2012/05/09/2491847.html 自己在学习中,对此原文的基础之上进行补充. 什么是缓冲区 缓冲 ...
- STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解)
介绍 FwLib_STC8 是一个针对STC8G, STC8H系列MCU的C语言封装库, 适用于基于这些MCU的快速原型验证. 项目地址: Gitee FwLib_STC8 镜像地址: GitHub ...
随机推荐
- linux环境下jdk部署配置
1.java官网下载相关的jdk包 2.配置系统环境变量,编辑/etc/profile文件,在文件的末尾添加一下信息: export JAVA_HOME=/usr/jdk1.8.0_101export ...
- springMvc json 参数
以前,一直以为在SpringMVC环境中,@RequestBody接收的是一个Json对象,一直在调试代码都没有成功,后来发现,其实 @RequestBody接收的是一个Json对象的字符串,而不是一 ...
- Batch the files in the directory
#!/bin/bash #sourceFolder = /home/bigdatagfts/pl62716/refdata #targetFolder = /home/bigdatagfts/pl62 ...
- 练习十七:python辨别数据类型
关于python辨别数据类型可以用python type()方法,那么想要查看一串字符中每项类型,并逐一输出要怎么处理?看下我是怎么处理的 习题要求:输入一行字符,分别统计其中英文字母.数字.空格.和 ...
- @Requestbody@ApiParam @PathVariable @RequestParam三者区别
一.问题描述 由于项目是前后端分离,因此后台使用的是spring boot,做成微服务,只暴露接口.接口设计风格为restful的风格,在get请求下,后台接收参数的注解为RequestBody时会报 ...
- 将GPT转换成MBR
准备一个pe启动盘 1.单击”运行“在弹出来的窗口输入cmd回车 2.在输入“diskpart”回车 3.在输入“list disk”显示硬盘信息,查看那个盘是gpt分区类型 4.输入“select ...
- 白话SpringCloud | 第一章:什么是SpringCloud
前言 作为SpringCloud的正式第一章,我们先来简单了解下SpringCloud相关知识点吧,内容可能比较多. 何为微服务 传统单体架构 服务化架构 微服务架构 什么是SpringCloud 核 ...
- DB2去重的几种方法
有两个意义上的重复记录,一是完全重复的记录,也即所有字段均重复的记录,二是部分关键字段重复的记录,比如Name字段重复,而其他字段不一定重复或都重复可以忽略. 例如下表:table1 用户办理套餐的记 ...
- spring batch 读取多个文件数据导入数据库
项目的目录结构 需要读取文件的的数据格式 applicatonContext.xml的配置 <?xml version="1.0" encoding="UTF-8& ...
- 从零开始的全栈工程师——js篇2.13(字符串与数组的方法)
基类Object的子类有 Function Array Number Boolean String Date Math RegExp 函数 数组 数字 布尔 字符串 日期 算数 正则 都 ...