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

    一、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

     1 class PCMUTypeBase : public AudioTypeBase
     2 {
     3     public:
     4         PCMUTypeBase() {Name.assign("PCMUTypeBase");};
     5         virtual ~PCMUTypeBase() {}; 
     6 
     7     public:
     8         virtual size_t CopyData(uint8_t * buf, uint8_t * data, size_t size) { return 0;};
     9         virtual int GetFlagOffset(const uint8_t * RTPPayload) { return -1; };
    10 
    11     // protected:
    12     //  std::string Name;
    13 };
    14 
    15 
    16 class PCMU_Audio : public PCMUTypeBase
    17 {
    18     public:
    19         PCMU_Audio() { Name.assign("PCMU_Audio"); };
    20         virtual ~PCMU_Audio() {}; 
    21     
    22     public:
    23         virtual size_t CopyData(uint8_t * buf, uint8_t * data, size_t size);
    24         virtual int GetFlagOffset(const uint8_t * RTPPayload);
    25 };

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

     1 size_t PCMU_Audio::CopyData(uint8_t * buf, uint8_t * data, size_t size)
     2 {
     3     size_t CopySize = 0;
     4     int Offset = 0;
     5     uint8_t * DataPointer = data;
     6 
     7     if(!buf || !data) return 0;
     8     Offset = GetFlagOffset(DataPointer);
     9 
    10     memcpy(buf+CopySize, data + Offset, size - Offset);
    11     CopySize += size - Offset;
    12 
    13     return CopySize;
    14 }
    15 
    16 int PCMU_Audio::GetFlagOffset(const uint8_t * rtp_payload)
    17 {
    18     return 0;
    19 }

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

     1 uint8_t * RtspClient::GetAudioData(MediaSession * media_session, uint8_t * buf, size_t * size, size_t max_size)
     2 {
     3     if(!media_session || !buf || !size) return NULL;
     4 
     5     *size = 0; 
     6 
     7     size_t SizeTmp = 0; 
     8     AudioTypeBase * AudioType;
     9 
    10     if(!media_session->GetMediaData(AudioBuffer.Buf, &SizeTmp)) return NULL;
    11     if(0 == SizeTmp) {
    12         cerr << "No RTP data" << endl;
    13         return NULL;
    14     }    
    15 
    16 
    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     }    
    23 
    24     if(SizeTmp > AudioBuffer.Size) {
    25         cerr << "Error: RTP Packet too large(" << SizeTmp << " bytes > " << AudioBuffer.Size << "bytes)" << endl;
    26         return NULL;
    27     }    
    28 
    29     if(*size + SizeTmp > max_size) {
    30         fprintf(stderr, "33[31mWARNING: NALU truncated because larger than buffer: %u(NALU size) > %u(Buffer size)33[0m
    ", *size + SizeTmp, max_size);
    31         return buf; 
    32     }    
    33 
    34     SizeTmp = AudioType->CopyData(buf + (*size), AudioBuffer.Buf, SizeTmp);
    35     *size += SizeTmp;
    36 
    37     return buf; 
    38 }

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

    上一篇                 回目录                下一篇

  • 相关阅读:
    delphi string.split 按照任意字符串分割语句
    学习 TTreeView [16]
    学习 TTreeView [15]
    delphi TClientDatset资料
    delphi7 clientdataset 详解
    为TMenuItem增加指针Data属性
    构建一个用于产品介绍的WEB应用
    图片延迟加载技术-Lazyload的应用
    你想不到的压缩方法:将javascript文件压缩成PNG图像存储
    如何更快速加载你的JS页面
  • 原文地址:https://www.cnblogs.com/ansersion/p/8870820.html
Copyright © 2011-2022 走看看