mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-02 01:21:33 +08:00
merge stamp
This commit is contained in:
parent
6518e5d448
commit
05a65d4961
@ -42,7 +42,48 @@ void Stamp::setPlayBack(bool playback) {
|
||||
_playback = playback;
|
||||
}
|
||||
|
||||
void Stamp::syncTo(Stamp &other){
|
||||
_sync_master = &other;
|
||||
_sync_finished = false;
|
||||
}
|
||||
|
||||
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);
|
||||
if(_sync_finished || modifyStamp || _playback){
|
||||
//自动生成时间戳或回放或同步完毕
|
||||
if(dts_out < 0) { dts_out = 0; }
|
||||
if(pts_out < 0) { pts_out = 0; }
|
||||
return;
|
||||
}
|
||||
|
||||
if(_sync_master && _sync_master->_last_dts){
|
||||
//音视频dts当前时间差
|
||||
int64_t dts_diff = _last_dts - _sync_master->_last_dts;
|
||||
if(ABS(dts_diff) < 5000){
|
||||
//如果绝对时间戳小于5秒,那么说明他们的起始时间戳是一致的,那么强制同步
|
||||
_last_relativeStamp = _relativeStamp;
|
||||
_relativeStamp = _sync_master->_relativeStamp + dts_diff;
|
||||
}
|
||||
//下次不用再强制同步
|
||||
_sync_master = nullptr;
|
||||
}
|
||||
|
||||
if (dts_out < 0 || dts_out < _last_relativeStamp) {
|
||||
//相对时间戳小于0,或者小于上次的时间戳,
|
||||
//那么说明是同步时间戳导致的,在这个过渡期内,我们一直返回上次的结果(目的是为了防止时间戳回退)
|
||||
pts_out = _last_relativeStamp + (pts_out - dts_out);
|
||||
dts_out = _last_relativeStamp;
|
||||
} else if(!_sync_master){
|
||||
//音视频同步过渡期完毕
|
||||
_sync_finished = true;
|
||||
}
|
||||
|
||||
if(pts_out < 0){
|
||||
pts_out = dts_out;
|
||||
}
|
||||
}
|
||||
|
||||
void Stamp::revise_l(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out,bool modifyStamp) {
|
||||
if(!pts){
|
||||
//没有播放时间戳,使其赋值为解码时间戳
|
||||
pts = dts;
|
||||
@ -52,10 +93,8 @@ void Stamp::revise(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out,
|
||||
//这是点播
|
||||
dts_out = dts;
|
||||
pts_out = pts;
|
||||
_relativeStamp = dts_out;
|
||||
_last_dts = dts;
|
||||
if (_dts_base == -1)
|
||||
_dts_base = dts;
|
||||
_relativeStamp = _npt_base + dts - _dts_base;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -65,6 +104,7 @@ void Stamp::revise(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out,
|
||||
if(_last_dts != dts){
|
||||
//时间戳发生变更
|
||||
if(modifyStamp){
|
||||
//内部自己生产时间戳
|
||||
_relativeStamp = _ticker.elapsedTime();
|
||||
}else{
|
||||
_relativeStamp += deltaStamp(dts);
|
||||
@ -80,15 +120,9 @@ void Stamp::revise(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out,
|
||||
}
|
||||
|
||||
pts_out = dts_out + pts_dts_diff;
|
||||
if(pts_out < 0){
|
||||
//时间戳不能小于0
|
||||
pts_out = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Stamp::setRelativeStamp(int64_t relativeStamp) {
|
||||
_dts_base = _last_dts;
|
||||
_npt_base = relativeStamp;
|
||||
_relativeStamp = relativeStamp;
|
||||
}
|
||||
|
||||
@ -141,7 +175,7 @@ bool DtsGenerator::getDts_l(uint32_t pts, uint32_t &dts){
|
||||
//已经出现多次非B帧的情况,那么我们就能知道P帧间B帧的个数
|
||||
_sorter_max_size = _frames_since_last_max_pts;
|
||||
//我们记录P帧间时间间隔(也就是多个B帧时间戳增量累计)
|
||||
_dts_pts_offset = (pts - _last_max_pts) / 2;
|
||||
_dts_pts_offset = (pts - _last_max_pts);
|
||||
}
|
||||
//遇到P帧或关键帧,连续B帧计数清零
|
||||
_frames_since_last_max_pts = 0;
|
||||
|
@ -32,6 +32,7 @@ public:
|
||||
private:
|
||||
int64_t _last_stamp = 0;
|
||||
};
|
||||
|
||||
//该类解决时间戳回环、回退问题
|
||||
//计算相对时间戳或者产生平滑时间戳
|
||||
class Stamp : public DeltaStamp{
|
||||
@ -66,17 +67,27 @@ public:
|
||||
* @param playback 是否为回放模式
|
||||
*/
|
||||
void setPlayBack(bool playback = true);
|
||||
|
||||
/**
|
||||
* 音视频同步用,音频应该同步于视频(只修改音频时间戳)
|
||||
* 因为音频时间戳修改后不影响播放速度
|
||||
*/
|
||||
void syncTo(Stamp &other);
|
||||
|
||||
private:
|
||||
void revise_l(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out,bool modifyStamp = false);
|
||||
private:
|
||||
int64_t _relativeStamp = 0;
|
||||
int64_t _last_dts = -1;
|
||||
int64_t _last_relativeStamp = 0;
|
||||
int64_t _last_dts = 0;
|
||||
SmoothTicker _ticker;
|
||||
bool _playback = false;
|
||||
|
||||
int64_t _dts_base = 0;
|
||||
int64_t _npt_base = 0;
|
||||
Stamp *_sync_master = nullptr;
|
||||
bool _sync_finished = true;
|
||||
};
|
||||
|
||||
|
||||
//dts生成器,
|
||||
//pts排序后就是dts
|
||||
class DtsGenerator{
|
||||
public:
|
||||
DtsGenerator() = default;
|
||||
@ -93,8 +104,6 @@ private:
|
||||
int _sorter_max_size = 0;
|
||||
int _count_sorter_max_size = 0;
|
||||
set<uint32_t> _pts_sorter;
|
||||
|
||||
|
||||
};
|
||||
|
||||
}//namespace mediakit
|
||||
|
Loading…
Reference in New Issue
Block a user