添加dts生成算法,兼容含B帧的rtsp推流

This commit is contained in:
xiongziliang
2020-01-14 10:04:24 +08:00
parent b55db11de3
commit 9fa6e9d8d9
14 changed files with 187 additions and 111 deletions

View File

@@ -106,11 +106,11 @@ void DevChannel::inputH264(const char* pcData, int iDataLen, uint32_t dts,uint32
}
H264Frame::Ptr frame = std::make_shared<H264Frame>();
frame->timeStamp = dts;
frame->ptsStamp = pts;
frame->buffer.assign("\x00\x00\x00\x01",4);
frame->buffer.append(pcData + prefixeSize, iDataLen - prefixeSize);
frame->iPrefixSize = 4;
frame->_dts = dts;
frame->_pts = pts;
frame->_buffer.assign("\x00\x00\x00\x01",4);
frame->_buffer.append(pcData + prefixeSize, iDataLen - prefixeSize);
frame->_prefix_size = 4;
inputFrame(frame);
}
@@ -131,11 +131,11 @@ void DevChannel::inputH265(const char* pcData, int iDataLen, uint32_t dts,uint32
}
H265Frame::Ptr frame = std::make_shared<H265Frame>();
frame->timeStamp = dts;
frame->ptsStamp = pts;
frame->buffer.assign("\x00\x00\x00\x01",4);
frame->buffer.append(pcData + prefixeSize, iDataLen - prefixeSize);
frame->iPrefixSize = 4;
frame->_dts = dts;
frame->_pts = pts;
frame->_buffer.assign("\x00\x00\x00\x01",4);
frame->_buffer.append(pcData + prefixeSize, iDataLen - prefixeSize);
frame->_prefix_size = 4;
inputFrame(frame);
}

View File

@@ -42,13 +42,14 @@ int64_t DeltaStamp::deltaStamp(int64_t stamp) {
}
int64_t ret = stamp - _last_stamp;
if(ABS(ret) < MAX_DELTA_STAMP){
//时间戳变化不明显
if(ret >= 0){
//时间戳增量为正,返回之
_last_stamp = stamp;
return ret;
//在直播情况下时间戳增量不得大于MAX_DELTA_STAMP
return ret < MAX_DELTA_STAMP ? ret : (_playback ? ret : 0);
}
//时间戳变化太明显可能回环了或者seek
//时间戳增量为负,说明时间戳回环了或回退
_last_stamp = stamp;
return _playback ? ret : 0;
}
@@ -99,4 +100,52 @@ int64_t Stamp::getRelativeStamp() const {
}
bool DtsGenerator::getDts(uint32_t pts, uint32_t &dts){
bool ret = false;
if(pts == _last_pts){
//pts未变返回上次结果
if(_last_dts){
dts = _last_dts;
ret = true;
}
return ret;
}
ret = getDts_l(pts,dts);
if(ret){
//保存本次结果
_last_dts = dts;
}
//记录上次pts
_last_pts = pts;
return ret;
}
bool DtsGenerator::getDts_l(uint32_t pts, uint32_t &dts){
if(pts > _last_max_pts){
if(!_sorter_max_size && _frames_since_last_max_pts && _count_sorter_max_size++ > 0){
_sorter_max_size = _frames_since_last_max_pts;
_dts_pts_offset = (pts - _last_max_pts) / 2;
InfoL << _sorter_max_size << " " << _dts_pts_offset;
}
_frames_since_last_max_pts = 0;
_last_max_pts = pts;
}
_pts_sorter.emplace(pts);
++_frames_since_last_max_pts;
if(_sorter_max_size && _pts_sorter.size() > _sorter_max_size){
auto it = _pts_sorter.begin();
dts = *it + _dts_pts_offset;
if(dts > pts){
//dts不能大于pts(基本不可能到达这个逻辑)
dts = pts;
}
_pts_sorter.erase(it);
return true;
}
return false;
}
}//namespace mediakit

View File

@@ -27,8 +27,9 @@
#ifndef ZLMEDIAKIT_STAMP_H
#define ZLMEDIAKIT_STAMP_H
#include "Util/TimeTicker.h"
#include <set>
#include <cstdint>
#include "Util/TimeTicker.h"
using namespace toolkit;
namespace mediakit {
@@ -88,6 +89,27 @@ private:
SmoothTicker _ticker;
};
class DtsGenerator{
public:
DtsGenerator() = default;
~DtsGenerator() = default;
bool getDts(uint32_t pts, uint32_t &dts);
private:
bool getDts_l(uint32_t pts, uint32_t &dts);
private:
uint32_t _dts_pts_offset = 0;
uint32_t _last_dts = 0;
uint32_t _last_pts = 0;
uint32_t _last_max_pts = 0;
int _frames_since_last_max_pts = 0;
int _sorter_max_size = 0;
int _count_sorter_max_size = 0;
set<uint32_t> _pts_sorter;
};
}//namespace mediakit
#endif //ZLMEDIAKIT_STAMP_H