一、myRtspClient音频解析架构

AudioTypeBase是处理解析各种编码的音频数据的接口类。处理MPA数据的MPEG_Audio类和处理g711-mulaw的PCMU_Audio类均从AudioTypeBase继承而来。AudioTypeBase最重要的接口为CopyData,它的作用就是将RTP接收到的实时数据(data)存放到用户的缓存区(buf),每当接收到1包新的RTP数据时,该函数就会得到调用。

二、myRtspClient视频解析架构

NALUTypeBase是处理解析各种编码的视频数据的接口类。处理H264的FU-A数据的FU_A类和处理H265的FUs数据的FUs_H265类均从NALUTypeBase继承而来。NALUTypeBase最重要的接口为CopyData,它的作用就是将RTP接收到的实时数据(data)存放到用户的缓存区(buf),每当接收到1包新的RTP数据时,该函数就会得到调用。

三、以g711-mulaw为例添加新的编码格式

相较于myRtspClient-1.2.3,myRtspClient-1.2.4增加了对g711-mulaw的支持。除去Makefile和注释,新版本添加和修改的源码总共100行左右。接下来我们将分析这100行代码。(历史版本:https://github.com/Ansersion/myRtspClient/releases)

首先我们构建2个类:PCMUTypeBase和PCMU_Audio,前者继承AudioTypeBase,后者继承前者。现在我们最主要的任务就是实现PCMU_Audio::CopyData和PCMU_Audio::GetFlagOffset

 class PCMUTypeBase : public AudioTypeBase
{
public:
PCMUTypeBase() {Name.assign("PCMUTypeBase");};
virtual ~PCMUTypeBase() {}; public:
virtual size_t CopyData(uint8_t * buf, uint8_t * data, size_t size) { return ;};
virtual int GetFlagOffset(const uint8_t * RTPPayload) { return -; }; // protected:
// std::string Name;
}; class PCMU_Audio : public PCMUTypeBase
{
public:
PCMU_Audio() { Name.assign("PCMU_Audio"); };
virtual ~PCMU_Audio() {}; public:
virtual size_t CopyData(uint8_t * buf, uint8_t * data, size_t size);
virtual int GetFlagOffset(const uint8_t * RTPPayload);
};

g711-mulaw的RTP格式很简单,除去RTP的报文头就是g711-mulaw的数据了,所以GetFlagOffset无需解析任何g711的头,直接返回0即可,CopyData也只要将RTP数据data直接复制到用户缓存buf中就行了。

 size_t PCMU_Audio::CopyData(uint8_t * buf, uint8_t * data, size_t size)
{
size_t CopySize = ;
int Offset = ;
uint8_t * DataPointer = data; if(!buf || !data) return ;
Offset = GetFlagOffset(DataPointer); memcpy(buf+CopySize, data + Offset, size - Offset);
CopySize += size - Offset; return CopySize;
} int PCMU_Audio::GetFlagOffset(const uint8_t * rtp_payload)
{
return ;
}

然后修改uint8_t * RtspClient::GetAudioData(MediaSession * media_session, uint8_t * buf, size_t * size, size_t max_size),注意以下代码红色字体部分。

 uint8_t * RtspClient::GetAudioData(MediaSession * media_session, uint8_t * buf, size_t * size, size_t max_size)
{
if(!media_session || !buf || !size) return NULL; *size = ; size_t SizeTmp = ;
AudioTypeBase * AudioType; if(!media_session->GetMediaData(AudioBuffer.Buf, &SizeTmp)) return NULL;
if( == SizeTmp) {
cerr << "No RTP data" << endl;
return NULL;
} 17 MyRegex Regex;
18 if(Regex.Regex(media_session->EncodeType.c_str(), "PCMU", true)) {
19 AudioType = &PCMU_AudioObj;
20 } else {
21 AudioType = &MPEG_AudioObj;
22 } if(SizeTmp > AudioBuffer.Size) {
cerr << "Error: RTP Packet too large(" << SizeTmp << " bytes > " << AudioBuffer.Size << "bytes)" << endl;
return NULL;
} if(*size + SizeTmp > max_size) {
fprintf(stderr, "\033[31mWARNING: NALU truncated because larger than buffer: %u(NALU size) > %u(Buffer size)\033[0m\n", *size + SizeTmp, max_size);
return buf;
} SizeTmp = AudioType->CopyData(buf + (*size), AudioBuffer.Buf, SizeTmp);
*size += SizeTmp; return buf;
}

至此,支持g711-mulaw的代码已经添加完毕。

上一篇                 回目录                下一篇

一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(九)以g711-mulaw为例添加新的编码格式解析支持的更多相关文章

  1. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(四)用户接口层之处理SDP报文

    当RTSP客户端向RTSP服务端发送DESCRIBE命令时,服务端理应当回复一条SDP报文. 该SDP报文中包含RTSP服务端的基本信息.所能提供的音视频媒体类型以及相应的负载能力,以下是一段SDP示 ...

  2. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(五)用户接口层之提取媒体流数据

    当RTSP客户端向RTSP服务端发送完PLAY命令后,RTSP服务端就会另外开启UDP端口(SDP协商定义的端口)发送RTP媒体流数据包.这些数据包之间会间隔一段时间(毫秒级)陆续被发送到RTSP客户 ...

  3. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(十)使用JRTPLIB传输RTP数据

    myRtspClient通过简单修改JRTPLIB的官方例程作为其RTP传输层实现.因为JRTPLIB使用的是CMAKE编译工具,这就是为什么编译myRtspClient时需要预装CMAKE. 该部分 ...

  4. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——解码篇:(一)用ffmpeg解码视频

    一.概述 myRTSPClient(RTSPClient)获取音视频数据之后,接下来的工作便是将音视频数据交给解码器去解码(ffmpeg),ffmpeg解码之后于是便有了呈现在终端用户(USER)面前 ...

  5. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(二)用户接口层之RtspClient类及其构造函数

    RtspClient类是myRTSPClient函数库所有特性集中实现的地方. 主要为用户提供: 1. RTSP协议通信接口函数,如DoOPTIONS(): 2. RTSP账号.密码设置函数,如Set ...

  6. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(一)概览

    myRTSPClient主要可以分成3个部分: 1. RTSPClient用户接口层: 2. RTP 音视频传输解析层: 3. RTP传输层. "RTSPClient用户接口层": ...

  7. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(三)用户接口层之RTSP命令

    截至版本1.2.3,myRtspClient函数库共支持以下6个RTSP命令: (1)OPTIONS (2)DESCRIBE (3)SETUP (4)PLAY (5)PAUSE (6)TEARDOWN ...

  8. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——解码篇:(三)一个简单的rtsp播放器

    该篇内容简单的将前两篇内容组合在一起,创建了2个线程,分别播放音频和视频. int main(int argc, char * argv[]) { RtspClient Client; pthread ...

  9. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(八)RTP音视频传输解析层之MPA传输格式

    一.MPEG RTP音频传输 相较H264的RTP传输格式,MPEGE音频传输格式则简单许多. 每一包MPEG音频RTP包都前缀一个4字节的Header,如下图(RFC2550) “MBZ”必须为0( ...

随机推荐

  1. Docker简介及Linux下安装

    什么是Docker? Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的.可移植的.自给自足的容器.开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机). ...

  2. node-sass 安装

    设置 export ELECTRON_MIRROR="https://npm.taobao.org/mirrors/electron/" export SASS_BINARY_SI ...

  3. ubuntu16.04下安装配置pl-svo

    Semi-direct Visual Odometry(SVO)安装配置 https://blog.csdn.net/seymour163/article/details/53947764 http: ...

  4. HDU 1002 - A + B Problem II - [高精度]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1002 Problem DescriptionI have a very simple problem ...

  5. 文本分类-TensorRT优化结果对比图

    做的文本二分类,使用tensorRT进行图优化和加速,输出预测概率结果对比如下: 从结果对比来看,概率值有微小的变化,但不影响最终的分类

  6. 3-idiots hdu4609 母函数+FFT 组合数学题

    http://acm.hdu.edu.cn/showproblem.php?pid=4609 题意:1e5个数,求取三个数能形成三角形的概率. 题解(这怎么会是fft入门题QAQ): 概率的算法就是三 ...

  7. 启用hive hwi方法

    hive启动hwi: ./hive --service hwi ls: cannot access /opt/cdh-5.3.6/hive-0.13.1/lib/hive-hwi-*.war: No ...

  8. ArcGIS API for JavaScript

    以3.14版本为例: 1.部署环境: 下载:https://developers.arcgis.com/downloads/apis-and-sdks?product=javascript# 部署:h ...

  9. 创建结点 与 分配内存 Function to create a Node. Allocates memory for a new node. 主动申请内存 链表 指针的写法

    Self Referential Data Structure in C - create a singly linked list http://www.how2lab.com/programmin ...

  10. Only the storage referenced by ptr is modified. No other storage locations are accessed by the call.

    free - C++ Reference http://www.cplusplus.com/reference/cstdlib/free/ Data races Only the storage re ...