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

时间:2023-03-09 04:05:13
一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(九)以g711-mulaw为例添加新的编码格式解析支持

一、myRtspClient音频解析架构

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

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

二、myRtspClient视频解析架构

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

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

三、以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的代码已经添加完毕。

上一篇                 回目录                下一篇