mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-22 10:40:05 +08:00
优化代码,提升可读性
This commit is contained in:
parent
fec7fe5b3b
commit
85f05adc06
@ -1 +1 @@
|
|||||||
Subproject commit f922d96f98108186e8d9bb9b468c83c0b37d9558
|
Subproject commit dd8928ddaecb71cbb5da447dbaf5af29b24b2e7d
|
@ -28,152 +28,164 @@
|
|||||||
#include "RtpReceiver.h"
|
#include "RtpReceiver.h"
|
||||||
|
|
||||||
#define POP_HEAD(trackidx) \
|
#define POP_HEAD(trackidx) \
|
||||||
auto it = _amapRtpSort[trackidx].begin(); \
|
auto it = _rtp_sort_cache_map[trackidx].begin(); \
|
||||||
onRtpSorted(it->second, trackidx); \
|
onRtpSorted(it->second, trackidx); \
|
||||||
_amapRtpSort[trackidx].erase(it);
|
_rtp_sort_cache_map[trackidx].erase(it);
|
||||||
|
|
||||||
# define AV_RB16(x) \
|
#define AV_RB16(x) \
|
||||||
((((const uint8_t*)(x))[0] << 8) | \
|
((((const uint8_t*)(x))[0] << 8) | \
|
||||||
((const uint8_t*)(x))[1])
|
((const uint8_t*)(x))[1])
|
||||||
|
|
||||||
|
#define RTP_MAX_SIZE (10 * 1024)
|
||||||
|
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
RtpReceiver::RtpReceiver() {}
|
RtpReceiver::RtpReceiver() {}
|
||||||
RtpReceiver::~RtpReceiver() {}
|
RtpReceiver::~RtpReceiver() {}
|
||||||
|
|
||||||
bool RtpReceiver::handleOneRtp(int iTrackidx,SdpTrack::Ptr &track, unsigned char *pucData, unsigned int uiLen) {
|
bool RtpReceiver::handleOneRtp(int track_index,SdpTrack::Ptr &track, unsigned char *rtp_raw_ptr, unsigned int rtp_raw_len) {
|
||||||
auto pt_ptr=_pktPool.obtain();
|
auto rtp_ptr = _rtp_pool.obtain();
|
||||||
auto &rtppt=*pt_ptr;
|
auto &rtp = *rtp_ptr;
|
||||||
auto length = uiLen + 4;
|
auto length = rtp_raw_len + 4;
|
||||||
|
|
||||||
rtppt.interleaved = track->_interleaved;
|
rtp.interleaved = track->_interleaved;
|
||||||
rtppt.mark = pucData[1] >> 7;
|
rtp.mark = rtp_raw_ptr[1] >> 7;
|
||||||
rtppt.PT = pucData[1] & 0x7F;
|
rtp.PT = rtp_raw_ptr[1] & 0x7F;
|
||||||
//序列号
|
//序列号
|
||||||
memcpy(&rtppt.sequence,pucData+2,2);//内存对齐
|
memcpy(&rtp.sequence,rtp_raw_ptr+2,2);//内存对齐
|
||||||
rtppt.sequence = ntohs(rtppt.sequence);
|
rtp.sequence = ntohs(rtp.sequence);
|
||||||
//时间戳
|
//时间戳
|
||||||
memcpy(&rtppt.timeStamp, pucData+4, 4);//内存对齐
|
memcpy(&rtp.timeStamp, rtp_raw_ptr+4, 4);//内存对齐
|
||||||
|
|
||||||
if(!track->_samplerate){
|
if(!track->_samplerate){
|
||||||
|
//无法把时间戳转换成毫秒
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//时间戳转换成毫秒
|
//时间戳转换成毫秒
|
||||||
rtppt.timeStamp = ntohl(rtppt.timeStamp) * 1000LL / track->_samplerate;
|
rtp.timeStamp = ntohl(rtp.timeStamp) * 1000LL / track->_samplerate;
|
||||||
//ssrc
|
//ssrc
|
||||||
memcpy(&rtppt.ssrc,pucData+8,4);//内存对齐
|
memcpy(&rtp.ssrc,rtp_raw_ptr+8,4);//内存对齐
|
||||||
rtppt.ssrc = ntohl(rtppt.ssrc);
|
rtp.ssrc = ntohl(rtp.ssrc);
|
||||||
rtppt.type = track->_type;
|
rtp.type = track->_type;
|
||||||
if (track->_ssrc == 0) {
|
|
||||||
track->_ssrc = rtppt.ssrc;
|
|
||||||
//保存SSRC
|
|
||||||
} else if (track->_ssrc != rtppt.ssrc) {
|
|
||||||
//ssrc错误
|
|
||||||
WarnL << "ssrc错误:" << rtppt.ssrc << " != " << track->_ssrc;
|
|
||||||
if (_aui32SsrcErrorCnt[iTrackidx]++ > 10) {
|
|
||||||
//ssrc切换后清除老数据
|
|
||||||
WarnL << "ssrc更换:" << track->_ssrc << " -> " << rtppt.ssrc;
|
|
||||||
_amapRtpSort[iTrackidx].clear();
|
|
||||||
track->_ssrc = rtppt.ssrc;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
_aui32SsrcErrorCnt[iTrackidx] = 0;
|
|
||||||
|
|
||||||
//获取rtp中媒体数据偏移量
|
if (track->_ssrc != rtp.ssrc) {
|
||||||
rtppt.offset = 12 + 4;
|
if (track->_ssrc == 0) {
|
||||||
int csrc = pucData[0] & 0x0f;
|
//保存SSRC至track对象
|
||||||
int ext = pucData[0] & 0x10;
|
track->_ssrc = rtp.ssrc;
|
||||||
rtppt.offset += 4 * csrc;
|
}else{
|
||||||
if (ext) {
|
//ssrc错误
|
||||||
if(uiLen < rtppt.offset){
|
WarnL << "ssrc错误:" << rtp.ssrc << " != " << track->_ssrc;
|
||||||
|
if (_ssrc_err_count[track_index]++ > 10) {
|
||||||
|
//ssrc切换后清除老数据
|
||||||
|
WarnL << "ssrc更换:" << track->_ssrc << " -> " << rtp.ssrc;
|
||||||
|
_rtp_sort_cache_map[track_index].clear();
|
||||||
|
track->_ssrc = rtp.ssrc;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* calculate the header extension length (stored as number of 32-bit words) */
|
|
||||||
ext = (AV_RB16(pucData + rtppt.offset - 2) + 1) << 2;
|
|
||||||
rtppt.offset += ext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(length - rtppt.offset <= 0){
|
//ssrc匹配正确,不匹配计数清零
|
||||||
WarnL << "无有效负载的rtp包:" << length << "<=" << (int)rtppt.offset;
|
_ssrc_err_count[track_index] = 0;
|
||||||
|
|
||||||
|
//获取rtp中媒体数据偏移量
|
||||||
|
rtp.offset = 12 + 4;
|
||||||
|
int csrc = rtp_raw_ptr[0] & 0x0f;
|
||||||
|
int ext = rtp_raw_ptr[0] & 0x10;
|
||||||
|
rtp.offset += 4 * csrc;
|
||||||
|
if (ext && rtp_raw_len >= rtp.offset) {
|
||||||
|
/* calculate the header extension length (stored as number of 32-bit words) */
|
||||||
|
ext = (AV_RB16(rtp_raw_ptr + rtp.offset - 2) + 1) << 2;
|
||||||
|
rtp.offset += ext;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(length <= rtp.offset){
|
||||||
|
WarnL << "无有效负载的rtp包:" << length << "<=" << (int)rtp.offset;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtppt.setCapacity(length);
|
if(length > RTP_MAX_SIZE){
|
||||||
rtppt.setSize(length);
|
WarnL << "超大的rtp包:" << length << ">" << RTP_MAX_SIZE;
|
||||||
uint8_t *payload_ptr = (uint8_t *)rtppt.data();
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//设置rtp负载长度
|
||||||
|
rtp.setCapacity(length);
|
||||||
|
rtp.setSize(length);
|
||||||
|
uint8_t *payload_ptr = (uint8_t *)rtp.data();
|
||||||
payload_ptr[0] = '$';
|
payload_ptr[0] = '$';
|
||||||
payload_ptr[1] = rtppt.interleaved;
|
payload_ptr[1] = rtp.interleaved;
|
||||||
payload_ptr[2] = uiLen >> 8;
|
payload_ptr[2] = rtp_raw_len >> 8;
|
||||||
payload_ptr[3] = (uiLen & 0x00FF);
|
payload_ptr[3] = (rtp_raw_len & 0x00FF);
|
||||||
//拷贝rtp负载
|
//拷贝rtp负载
|
||||||
memcpy(payload_ptr + 4, pucData, uiLen);
|
memcpy(payload_ptr + 4, rtp_raw_ptr, rtp_raw_len);
|
||||||
|
//排序rtp
|
||||||
/////////////////////////////////RTP排序逻辑///////////////////////////////////
|
sortRtp(rtp_ptr,track_index);
|
||||||
if(rtppt.sequence != _aui16LastSeq[iTrackidx] + 1 && _aui16LastSeq[iTrackidx] != 0){
|
|
||||||
//包乱序或丢包
|
|
||||||
_aui32SeqOkCnt[iTrackidx] = 0;
|
|
||||||
_abSortStarted[iTrackidx] = true;
|
|
||||||
// WarnL << "包乱序或丢包:" << iTrackidx <<" " << rtppt.sequence << " " << _aui16LastSeq[iTrackidx];
|
|
||||||
if(_aui16LastSeq[iTrackidx] > rtppt.sequence && _aui16LastSeq[iTrackidx] - rtppt.sequence > 0xFF){
|
|
||||||
//sequence回环,清空所有排序缓存
|
|
||||||
while (_amapRtpSort[iTrackidx].size()) {
|
|
||||||
POP_HEAD(iTrackidx)
|
|
||||||
}
|
|
||||||
++_clcyeCount[iTrackidx];
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
//正确序列的包
|
|
||||||
_aui32SeqOkCnt[iTrackidx]++;
|
|
||||||
}
|
|
||||||
_aui16LastSeq[iTrackidx] = rtppt.sequence;
|
|
||||||
|
|
||||||
//开始排序缓存
|
|
||||||
if (_abSortStarted[iTrackidx]) {
|
|
||||||
_amapRtpSort[iTrackidx].emplace(rtppt.sequence, pt_ptr);
|
|
||||||
GET_CONFIG(uint32_t,clearCount,Rtp::kClearCount);
|
|
||||||
GET_CONFIG(uint32_t,maxRtpCount,Rtp::kMaxRtpCount);
|
|
||||||
if (_aui32SeqOkCnt[iTrackidx] >= clearCount) {
|
|
||||||
//网络环境改善,需要清空排序缓存
|
|
||||||
_aui32SeqOkCnt[iTrackidx] = 0;
|
|
||||||
_abSortStarted[iTrackidx] = false;
|
|
||||||
while (_amapRtpSort[iTrackidx].size()) {
|
|
||||||
POP_HEAD(iTrackidx)
|
|
||||||
}
|
|
||||||
} else if (_amapRtpSort[iTrackidx].size() >= maxRtpCount) {
|
|
||||||
//排序缓存溢出
|
|
||||||
POP_HEAD(iTrackidx)
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
//正确序列
|
|
||||||
onRtpSorted(pt_ptr, iTrackidx);
|
|
||||||
}
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtpReceiver::clear() {
|
void RtpReceiver::sortRtp(const RtpPacket::Ptr &rtp,int track_index){
|
||||||
CLEAR_ARR(_aui16LastSeq)
|
if(rtp->sequence != _last_seq[track_index] + 1 && _last_seq[track_index] != 0){
|
||||||
CLEAR_ARR(_aui32SsrcErrorCnt)
|
//包乱序或丢包
|
||||||
CLEAR_ARR(_aui32SeqOkCnt)
|
_seq_ok_count[track_index] = 0;
|
||||||
CLEAR_ARR(_abSortStarted)
|
_sort_started[track_index] = true;
|
||||||
CLEAR_ARR(_clcyeCount)
|
if(_last_seq[track_index] > rtp->sequence && _last_seq[track_index] - rtp->sequence > 0xFF){
|
||||||
|
//sequence回环,清空所有排序缓存
|
||||||
|
while (_rtp_sort_cache_map[track_index].size()) {
|
||||||
|
POP_HEAD(track_index)
|
||||||
|
}
|
||||||
|
++_seq_cycle_count[track_index];
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
//正确序列的包
|
||||||
|
_seq_ok_count[track_index]++;
|
||||||
|
}
|
||||||
|
|
||||||
_amapRtpSort[0].clear();
|
_last_seq[track_index] = rtp->sequence;
|
||||||
_amapRtpSort[1].clear();
|
|
||||||
|
//开始排序缓存
|
||||||
|
if (_sort_started[track_index]) {
|
||||||
|
_rtp_sort_cache_map[track_index].emplace(rtp->sequence, rtp);
|
||||||
|
GET_CONFIG(uint32_t,clearCount,Rtp::kClearCount);
|
||||||
|
GET_CONFIG(uint32_t,maxRtpCount,Rtp::kMaxRtpCount);
|
||||||
|
if (_seq_ok_count[track_index] >= clearCount) {
|
||||||
|
//网络环境改善,需要清空排序缓存
|
||||||
|
_seq_ok_count[track_index] = 0;
|
||||||
|
_sort_started[track_index] = false;
|
||||||
|
while (_rtp_sort_cache_map[track_index].size()) {
|
||||||
|
POP_HEAD(track_index)
|
||||||
|
}
|
||||||
|
} else if (_rtp_sort_cache_map[track_index].size() >= maxRtpCount) {
|
||||||
|
//排序缓存溢出
|
||||||
|
POP_HEAD(track_index)
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
//正确序列
|
||||||
|
onRtpSorted(rtp, track_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtpReceiver::clear() {
|
||||||
|
CLEAR_ARR(_last_seq)
|
||||||
|
CLEAR_ARR(_ssrc_err_count)
|
||||||
|
CLEAR_ARR(_seq_ok_count)
|
||||||
|
CLEAR_ARR(_sort_started)
|
||||||
|
CLEAR_ARR(_seq_cycle_count)
|
||||||
|
|
||||||
|
_rtp_sort_cache_map[0].clear();
|
||||||
|
_rtp_sort_cache_map[1].clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtpReceiver::setPoolSize(int size) {
|
void RtpReceiver::setPoolSize(int size) {
|
||||||
_pktPool.setSize(size);
|
_rtp_pool.setSize(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int RtpReceiver::getJitterSize(int iTrackidx){
|
int RtpReceiver::getJitterSize(int iTrackidx){
|
||||||
return _amapRtpSort[iTrackidx].size();
|
return _rtp_sort_cache_map[iTrackidx].size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int RtpReceiver::getCycleCount(int iTrackidx){
|
int RtpReceiver::getCycleCount(int iTrackidx){
|
||||||
return _clcyeCount[iTrackidx];
|
return _seq_cycle_count[iTrackidx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,33 +48,41 @@ protected:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 输入数据指针生成并排序rtp包
|
* 输入数据指针生成并排序rtp包
|
||||||
* @param iTrackidx track下标索引
|
* @param track_index track下标索引
|
||||||
* @param track sdp track相关信息
|
* @param track sdp track相关信息
|
||||||
* @param pucData rtp数据指针
|
* @param rtp_raw_ptr rtp数据指针
|
||||||
* @param uiLen rtp数据指针长度
|
* @param rtp_raw_len rtp数据指针长度
|
||||||
* @return 解析成功返回true
|
* @return 解析成功返回true
|
||||||
*/
|
*/
|
||||||
bool handleOneRtp(int iTrackidx,SdpTrack::Ptr &track, unsigned char *pucData, unsigned int uiLen);
|
bool handleOneRtp(int track_index,SdpTrack::Ptr &track, unsigned char *rtp_raw_ptr, unsigned int rtp_raw_len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rtp数据包排序后输出
|
* rtp数据包排序后输出
|
||||||
* @param rtppt rtp数据包
|
* @param rtppt rtp数据包
|
||||||
* @param trackidx track索引
|
* @param trackidx track索引
|
||||||
*/
|
*/
|
||||||
virtual void onRtpSorted(const RtpPacket::Ptr &rtppt, int trackidx){}
|
virtual void onRtpSorted(const RtpPacket::Ptr &rtp, int trackidx){}
|
||||||
void clear();
|
void clear();
|
||||||
void setPoolSize(int size);
|
void setPoolSize(int size);
|
||||||
int getJitterSize(int iTrackidx);
|
int getJitterSize(int iTrackidx);
|
||||||
int getCycleCount(int iTrackidx);
|
int getCycleCount(int iTrackidx);
|
||||||
private:
|
private:
|
||||||
uint32_t _aui32SsrcErrorCnt[2] = { 0, 0 };
|
void sortRtp(const RtpPacket::Ptr &rtp , int track_index);
|
||||||
/* RTP包排序所用参数 */
|
private:
|
||||||
uint16_t _aui16LastSeq[2] = { 0 , 0 };
|
//ssrc不匹配计数
|
||||||
uint32_t _aui32SeqOkCnt[2] = { 0 , 0};
|
uint32_t _ssrc_err_count[2] = { 0, 0 };
|
||||||
uint32_t _clcyeCount[2] = { 0 , 0};
|
//上次seq
|
||||||
bool _abSortStarted[2] = { 0 , 0};
|
uint16_t _last_seq[2] = { 0 , 0 };
|
||||||
map<uint16_t , RtpPacket::Ptr> _amapRtpSort[2];
|
//seq连续次数计数
|
||||||
RtspMediaSource::PoolType _pktPool;
|
uint32_t _seq_ok_count[2] = { 0 , 0};
|
||||||
|
//seq回环次数计数
|
||||||
|
uint32_t _seq_cycle_count[2] = { 0 , 0};
|
||||||
|
//是否开始seq排序
|
||||||
|
bool _sort_started[2] = { 0 , 0};
|
||||||
|
//rtp排序缓存,根据seq排序
|
||||||
|
map<uint16_t , RtpPacket::Ptr> _rtp_sort_cache_map[2];
|
||||||
|
//rtp循环池
|
||||||
|
RtspMediaSource::PoolType _rtp_pool;
|
||||||
};
|
};
|
||||||
|
|
||||||
}//namespace mediakit
|
}//namespace mediakit
|
||||||
|
Loading…
Reference in New Issue
Block a user