逻辑总结
解复用的RTP流工具,RTP 流可以携带多种不同类型的数据(音频、视频等),解复用器通过 InputData
方法接收 RTP 数据并通过回调将音频或视频数据传递给实现了 RTPDemuxerInterface
的类。通过这种方式,RTP 数据可以被解码并播放,或者进行进一步的处理
回调机制实现
RTPDemuxer
通过SetCallBack
方法设置一个回调接口(RTPDemuxerInterface
)。通过该接口,RTPDemuxer
可以将解复用后的音频和视频数据传递给外部实现。- 在处理 RTP 数据时,
RTPDemuxer
可能会调用OnVideoData
或OnAudioData
来通知外部类,分别传递解复用的视频或音频数据。
数据输入与处理逻辑
外部代码可以调用 InputData
方法,将 RTP 数据输入到 RTPDemuxer
类中。根据输入数据的内容,RTPDemuxer
会解复用并调用回调函数,将音频或视频数据传递给实现了 RTPDemuxerInterface
接口的类
负载类型设置
SetPayloadType
方法允许设置数据的负载类型(如音频或视频编码格式),帮助解复用器区分数据的类型。负载类型可以用于解析 RTP 包并提取正确的音视频数据
原理总结
整体流程类似于一个外卖点餐系统
- 外卖客户(RTPDemuxerInterface):负责接收音频和视频数据,就像客户接受视频片段或歌曲一样。
- 厨房(RTPDemuxer):根据顾客的需求,准备视频或音频菜品,并通过回调将其交给外卖客户。
- 数据流转:通过厨房(解复用器)处理 RTP 数据流,并根据顾客需求(回调)将视频或音频数据分别送达顾客
外卖客户(RTPDemuxerInterface)
class RTPDemuxerInterface {
public:
virtual void OnVideoData(int64_t pts, const uint8_t* data, size_t size) = 0; //video demuxer only
virtual void OnAudioData(int64_t pts, const uint8_t* data, size_t size) = 0; //audio demuxer only
};
类似于最终接收数据的客户,其基本需求就是想要音频和视频两种类型的数据
厨房(RTPDemuxer)
负责将食材(RTP 数据流)处理成餐品(音视频数据)的地方。厨师会根据客户的需求做不同的菜品(音频或视频)
class RTPDemuxer{
public:
virtual void InputData(const uint8_t* data, size_t size) = 0;
void SetCallBack(RTPDemuxerInterface *call_back) {call_back_ = call_back; return;}
void SetPayloadType(int payload){payload_ = payload; return;}
protected:
RTPDemuxerInterface *call_back_ = NULL;
int payload_;
};
InputData
:顾客(外卖客户)将食材(原料数据)交给厨师,厨师开始处理。这里的食材就是原始的 RTP 数据流SetCallBack
:厨师接到外卖订单,并知道客户对食物的具体需求(电影或者音乐)。厨师将客户(回调接口)和订单(RTP 数据流)进行配对,确保最后的菜品送到对的客户手中SetPayloadType
:顾客(外卖客户)指定需要的菜肴类型(如:电影或歌曲)。厨师需要知道要做的是电影(视频)还是歌曲(音频)
实现逻辑分析
假设厨房收到一份订单,顾客要一份包含电影片段的视频数据和一份包含歌曲的音频数据。厨房(厨师)会根据这份订单将数据处理成视频和音频,并通过回调将菜肴(数据)送到顾客(外卖客户)手中
通过该种逻辑将客户和厨房进行分离,厨房(解复用器)和顾客(回调接口)之间保持解耦。厨师并不知道每个顾客的具体需求,它只负责处理好订单并通过回调送去
实现分析
RTPDemuxerInterface 类
定义两个纯虚函数,分别用于处理视频和音频的数据
class RTPDemuxerInterface {
public:
virtual void OnVideoData(int64_t pts, const uint8_t* data, size_t size) = 0; //video demuxer only
virtual void OnAudioData(int64_t pts, const uint8_t* data, size_t size) = 0; //audio demuxer only
};
RTPDemuxer 类
class RTPDemuxer{
public:
virtual void InputData(const uint8_t* data, size_t size) = 0;
void SetCallBack(RTPDemuxerInterface *call_back) {call_back_ = call_back; return;}
void SetPayloadType(int payload){payload_ = payload; return;}
protected:
RTPDemuxerInterface *call_back_ = NULL;
int payload_;
};
基础类,负责提供RTP数据处理的核心功能
- InputData:接收RTP数据包,然后提取出其中的音视频数据
- SetCalllBack:设置回调函数
- SetPayloadType:设置数据的负载类型
整体代码
#ifndef RTP_DEMUXER_
#define RTP_DEMUXER_
#include <iostream>
#include <stdint.h>
#include <arpa/inet.h>
#include "rtsp_common.h"
class RTPDemuxerInterface {
public:
virtual void OnVideoData(int64_t pts, const uint8_t* data, size_t size) = 0; //video demuxer only
virtual void OnAudioData(int64_t pts, const uint8_t* data, size_t size) = 0; //audio demuxer only
};
class RTPDemuxer{
public:
virtual void InputData(const uint8_t* data, size_t size) = 0;
void SetCallBack(RTPDemuxerInterface *call_back) {call_back_ = call_back; return;}
void SetPayloadType(int payload){payload_ = payload; return;}
protected:
RTPDemuxerInterface *call_back_ = NULL;
int payload_;
};
#endif