mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-10-30 16:27:36 +08:00
完善相对时间戳逻辑, 完善同步机制, 解决相对时间戳不同步的问题
默认禁止时间戳回退并设置最大跳跃幅度为300毫秒 rtsp恢复产生ntp时间戳 由于绝对时间戳可能跳跃回退,之前在求相对时间戳时会导致音视频不同步。 现在求相对时间戳逻辑经过修改,已经支持同步功能,所以恢复rtp ntp时间戳逻辑
This commit is contained in:
parent
bd22c44ee9
commit
0f4e0e1076
@ -20,8 +20,13 @@ using namespace toolkit;
|
|||||||
|
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
int64_t DeltaStamp::relativeStamp(int64_t stamp) {
|
DeltaStamp::DeltaStamp() {
|
||||||
_relative_stamp += deltaStamp(stamp);
|
// 时间戳最大允许跳跃300ms
|
||||||
|
_max_delta = 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t DeltaStamp::relativeStamp(int64_t stamp, bool enable_rollback) {
|
||||||
|
_relative_stamp += deltaStamp(stamp, enable_rollback);
|
||||||
return _relative_stamp;
|
return _relative_stamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,7 +34,7 @@ int64_t DeltaStamp::relativeStamp() {
|
|||||||
return _relative_stamp;
|
return _relative_stamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t DeltaStamp::deltaStamp(int64_t stamp) {
|
int64_t DeltaStamp::deltaStamp(int64_t stamp, bool enable_rollback) {
|
||||||
if (!_last_stamp) {
|
if (!_last_stamp) {
|
||||||
// 第一次计算时间戳增量,时间戳增量为0
|
// 第一次计算时间戳增量,时间戳增量为0
|
||||||
if (stamp) {
|
if (stamp) {
|
||||||
@ -43,14 +48,25 @@ int64_t DeltaStamp::deltaStamp(int64_t stamp) {
|
|||||||
// 时间戳增量为正,返回之
|
// 时间戳增量为正,返回之
|
||||||
_last_stamp = stamp;
|
_last_stamp = stamp;
|
||||||
// 在直播情况下,时间戳增量不得大于MAX_DELTA_STAMP,否则强制相对时间戳加1
|
// 在直播情况下,时间戳增量不得大于MAX_DELTA_STAMP,否则强制相对时间戳加1
|
||||||
return ret < MAX_DELTA_STAMP ? ret : 1;
|
if (ret > _max_delta) {
|
||||||
|
needSync();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 时间戳增量为负,说明时间戳回环了或回退了
|
// 时间戳增量为负,说明时间戳回环了或回退了
|
||||||
_last_stamp = stamp;
|
_last_stamp = stamp;
|
||||||
|
if (!enable_rollback || -ret > _max_delta) {
|
||||||
|
// 不允许回退或者回退太多了, 强制时间戳加1
|
||||||
|
needSync();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
// 如果时间戳回退不多,那么返回负值,否则返回加1
|
void DeltaStamp::setMaxDelta(size_t max_delta) {
|
||||||
return -ret < MAX_DELTA_STAMP ? ret : 1;
|
_max_delta = max_delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stamp::setPlayBack(bool playback) {
|
void Stamp::setPlayBack(bool playback) {
|
||||||
@ -58,9 +74,18 @@ void Stamp::setPlayBack(bool playback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Stamp::syncTo(Stamp &other) {
|
void Stamp::syncTo(Stamp &other) {
|
||||||
|
_need_sync = true;
|
||||||
_sync_master = &other;
|
_sync_master = &other;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Stamp::needSync() {
|
||||||
|
_need_sync = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stamp::enableRollback(bool flag) {
|
||||||
|
_enable_rollback = flag;
|
||||||
|
}
|
||||||
|
|
||||||
// 限制dts回退
|
// 限制dts回退
|
||||||
void Stamp::revise(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out, bool modifyStamp) {
|
void Stamp::revise(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out, bool modifyStamp) {
|
||||||
revise_l(dts, pts, dts_out, pts_out, modifyStamp);
|
revise_l(dts, pts, dts_out, pts_out, modifyStamp);
|
||||||
@ -87,15 +112,26 @@ void Stamp::revise_l(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_ou
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_sync_master && _sync_master->_last_dts_in) {
|
// 需要同步时间戳
|
||||||
|
if (_sync_master && _sync_master->_last_dts_in && (_need_sync || _sync_master->_need_sync)) {
|
||||||
// 音视频dts当前时间差
|
// 音视频dts当前时间差
|
||||||
int64_t dts_diff = _last_dts_in - _sync_master->_last_dts_in;
|
int64_t dts_diff = _last_dts_in - _sync_master->_last_dts_in;
|
||||||
if (ABS(dts_diff) < 5000) {
|
if (ABS(dts_diff) < 5000) {
|
||||||
// 如果绝对时间戳小于5秒,那么说明他们的起始时间戳是一致的,那么强制同步
|
// 如果绝对时间戳小于5秒,那么说明他们的起始时间戳是一致的,那么强制同步
|
||||||
_relative_stamp = _sync_master->_relative_stamp + dts_diff;
|
auto target_stamp = _sync_master->_relative_stamp + dts_diff;
|
||||||
|
if (target_stamp > _relative_stamp || _enable_rollback) {
|
||||||
|
// 强制同步后,时间戳增加跳跃了,或允许回退
|
||||||
|
TraceL << "Relative stamp changed: " << _relative_stamp << " -> " << target_stamp;
|
||||||
|
_relative_stamp = target_stamp;
|
||||||
|
} else {
|
||||||
|
// 不允许回退, 则让另外一个Track的时间戳增长
|
||||||
|
target_stamp = _relative_stamp - dts_diff;
|
||||||
|
TraceL << "Relative stamp changed: " << _sync_master->_relative_stamp << " -> " << target_stamp;
|
||||||
|
_sync_master->_relative_stamp = target_stamp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// 下次不用再强制同步
|
_need_sync = false;
|
||||||
_sync_master = nullptr;
|
_sync_master->_need_sync = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +160,7 @@ void Stamp::revise_l2(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_o
|
|||||||
// 内部自己生产时间戳
|
// 内部自己生产时间戳
|
||||||
_relative_stamp = _ticker.elapsedTime();
|
_relative_stamp = _ticker.elapsedTime();
|
||||||
} else {
|
} else {
|
||||||
_relative_stamp += deltaStamp(dts);
|
_relative_stamp += deltaStamp(dts, _enable_rollback);
|
||||||
}
|
}
|
||||||
_last_dts_in = dts;
|
_last_dts_in = dts;
|
||||||
}
|
}
|
||||||
|
@ -19,19 +19,27 @@ namespace mediakit {
|
|||||||
|
|
||||||
class DeltaStamp{
|
class DeltaStamp{
|
||||||
public:
|
public:
|
||||||
DeltaStamp() = default;
|
DeltaStamp();
|
||||||
~DeltaStamp() = default;
|
~DeltaStamp() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算时间戳增量
|
* 计算时间戳增量
|
||||||
* @param stamp 绝对时间戳
|
* @param stamp 绝对时间戳
|
||||||
|
* @param enable_rollback 是否允许相当时间戳回退
|
||||||
* @return 时间戳增量
|
* @return 时间戳增量
|
||||||
*/
|
*/
|
||||||
int64_t deltaStamp(int64_t stamp);
|
int64_t deltaStamp(int64_t stamp, bool enable_rollback = true);
|
||||||
int64_t relativeStamp(int64_t stamp);
|
int64_t relativeStamp(int64_t stamp, bool enable_rollback = true);
|
||||||
int64_t relativeStamp();
|
int64_t relativeStamp();
|
||||||
|
|
||||||
private:
|
// 设置最大允许回退或跳跃幅度
|
||||||
|
void setMaxDelta(size_t max_delta);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void needSync() {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int _max_delta;
|
||||||
int64_t _last_stamp = 0;
|
int64_t _last_stamp = 0;
|
||||||
int64_t _relative_stamp = 0;
|
int64_t _relative_stamp = 0;
|
||||||
};
|
};
|
||||||
@ -77,6 +85,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
void syncTo(Stamp &other);
|
void syncTo(Stamp &other);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否允许时间戳回退
|
||||||
|
*/
|
||||||
|
void enableRollback(bool flag);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//主要实现音视频时间戳同步功能
|
//主要实现音视频时间戳同步功能
|
||||||
void revise_l(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out,bool modifyStamp = false);
|
void revise_l(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out,bool modifyStamp = false);
|
||||||
@ -84,13 +97,18 @@ private:
|
|||||||
//主要实现获取相对时间戳功能
|
//主要实现获取相对时间戳功能
|
||||||
void revise_l2(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out,bool modifyStamp = false);
|
void revise_l2(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out,bool modifyStamp = false);
|
||||||
|
|
||||||
|
void needSync() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool _playback = false;
|
||||||
|
bool _need_sync = false;
|
||||||
|
// 默认不允许时间戳回滚
|
||||||
|
bool _enable_rollback = false;
|
||||||
int64_t _relative_stamp = 0;
|
int64_t _relative_stamp = 0;
|
||||||
int64_t _last_dts_in = 0;
|
int64_t _last_dts_in = 0;
|
||||||
int64_t _last_dts_out = 0;
|
int64_t _last_dts_out = 0;
|
||||||
int64_t _last_pts_out = 0;
|
int64_t _last_pts_out = 0;
|
||||||
toolkit::SmoothTicker _ticker;
|
toolkit::SmoothTicker _ticker;
|
||||||
bool _playback = false;
|
|
||||||
Stamp *_sync_master = nullptr;
|
Stamp *_sync_master = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
|
|
||||||
#define ENABLE_NTP_STAMP 0
|
#define ENABLE_NTP_STAMP 1
|
||||||
|
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
@ -78,6 +78,10 @@ bool RtspMuxer::addTrack(const Track::Ptr &track) {
|
|||||||
//添加其sdp
|
//添加其sdp
|
||||||
_sdp.append(sdp->getSdp());
|
_sdp.append(sdp->getSdp());
|
||||||
trySyncTrack();
|
trySyncTrack();
|
||||||
|
|
||||||
|
// rtp的时间戳是pts,允许回退
|
||||||
|
_stamp[TrackAudio].enableRollback(true);
|
||||||
|
_stamp[TrackVideo].enableRollback(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user