完善相对时间戳逻辑, 完善同步机制, 解决相对时间戳不同步的问题

This commit is contained in:
xia-chu 2023-11-25 10:43:51 +08:00
parent db0818c8d2
commit 46c6ff038c
2 changed files with 69 additions and 16 deletions

View File

@ -20,8 +20,12 @@ using namespace toolkit;
namespace mediakit { namespace mediakit {
int64_t DeltaStamp::relativeStamp(int64_t stamp) { DeltaStamp::DeltaStamp() {
_relative_stamp += deltaStamp(stamp); _max_delta = MAX_DELTA_STAMP;
}
int64_t DeltaStamp::relativeStamp(int64_t stamp, bool enable_rollback) {
_relative_stamp += deltaStamp(stamp, enable_rollback);
return _relative_stamp; return _relative_stamp;
} }
@ -29,7 +33,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 +47,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 +73,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 +111,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;
} }
// 下次不用再强制同步 }
_sync_master = nullptr; _need_sync = false;
_sync_master->_need_sync = false;
} }
} }
@ -124,7 +159,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;
} }

View File

@ -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:
size_t _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,17 @@ 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 = true;
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;
}; };
@ -106,6 +123,7 @@ private:
bool getDts_l(uint64_t pts, uint64_t &dts); bool getDts_l(uint64_t pts, uint64_t &dts);
private: private:
bool _enable_rollback = true;
uint64_t _dts_pts_offset = 0; uint64_t _dts_pts_offset = 0;
uint64_t _last_dts = 0; uint64_t _last_dts = 0;
uint64_t _last_pts = 0; uint64_t _last_pts = 0;