mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-26 04:31:37 +08:00
rtmp播放时,取相对时间戳逻辑确保时间戳同步
This commit is contained in:
parent
920f06a996
commit
a4d7b3463e
@ -42,7 +42,40 @@ void Stamp::setPlayBack(bool playback) {
|
|||||||
_playback = playback;
|
_playback = playback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Stamp::makeRelation(Stamp &other){
|
||||||
|
_related = &other;
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
if(modifyStamp || _playback){
|
||||||
|
//自动生成时间戳或回放,不需要做音视频同步
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_related && _related->_last_dts){
|
||||||
|
//音视频dts当前时间差
|
||||||
|
int64_t dts_diff = _last_dts - _related->_last_dts;
|
||||||
|
if(ABS(dts_diff) < 5000){
|
||||||
|
//如果绝对时间戳小于5秒,那么说明他们的起始时间戳是一致的,那么强制同步
|
||||||
|
_last_relativeStamp = _relativeStamp;
|
||||||
|
_relativeStamp = _related->_relativeStamp + dts_diff;
|
||||||
|
dts_out += dts_diff;
|
||||||
|
pts_out += dts_diff;
|
||||||
|
// DebugL << "音视频同步事件差:" << dts_diff;
|
||||||
|
}
|
||||||
|
//下次不用再强制同步
|
||||||
|
_related = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dts_out < 0){
|
||||||
|
//相对时间戳小于0,那么说明是同步时间戳导致的,在这个过渡期内,我们一直返回上次的结果(目的是为了防止时间戳回退)
|
||||||
|
pts_out = _last_relativeStamp + (pts_out - dts_out);
|
||||||
|
dts_out = _last_relativeStamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stamp::revise_l(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out,bool modifyStamp) {
|
||||||
if(!pts){
|
if(!pts){
|
||||||
//没有播放时间戳,使其赋值为解码时间戳
|
//没有播放时间戳,使其赋值为解码时间戳
|
||||||
pts = dts;
|
pts = dts;
|
||||||
@ -53,6 +86,7 @@ void Stamp::revise(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out,
|
|||||||
dts_out = dts;
|
dts_out = dts;
|
||||||
pts_out = pts;
|
pts_out = pts;
|
||||||
_relativeStamp = dts_out;
|
_relativeStamp = dts_out;
|
||||||
|
_last_dts = dts;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,6 +96,7 @@ void Stamp::revise(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out,
|
|||||||
if(_last_dts != dts){
|
if(_last_dts != dts){
|
||||||
//时间戳发生变更
|
//时间戳发生变更
|
||||||
if(modifyStamp){
|
if(modifyStamp){
|
||||||
|
//内部自己生产时间戳
|
||||||
_relativeStamp = _ticker.elapsedTime();
|
_relativeStamp = _ticker.elapsedTime();
|
||||||
}else{
|
}else{
|
||||||
_relativeStamp += deltaStamp(dts);
|
_relativeStamp += deltaStamp(dts);
|
||||||
|
@ -32,6 +32,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
int64_t _last_stamp = 0;
|
int64_t _last_stamp = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//该类解决时间戳回环、回退问题
|
//该类解决时间戳回环、回退问题
|
||||||
//计算相对时间戳或者产生平滑时间戳
|
//计算相对时间戳或者产生平滑时间戳
|
||||||
class Stamp : public DeltaStamp{
|
class Stamp : public DeltaStamp{
|
||||||
@ -66,14 +67,25 @@ public:
|
|||||||
* @param playback 是否为回放模式
|
* @param playback 是否为回放模式
|
||||||
*/
|
*/
|
||||||
void setPlayBack(bool playback = true);
|
void setPlayBack(bool playback = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 产生关联,用于音视频同步用
|
||||||
|
*/
|
||||||
|
void makeRelation(Stamp &other);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void revise_l(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out,bool modifyStamp = false);
|
||||||
private:
|
private:
|
||||||
int64_t _relativeStamp = 0;
|
int64_t _relativeStamp = 0;
|
||||||
int64_t _last_dts = -1;
|
int64_t _last_relativeStamp = 0;
|
||||||
|
int64_t _last_dts = 0;
|
||||||
SmoothTicker _ticker;
|
SmoothTicker _ticker;
|
||||||
bool _playback = false;
|
bool _playback = false;
|
||||||
|
Stamp *_related = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//dts生成器,
|
||||||
|
//pts排序后就是dts
|
||||||
class DtsGenerator{
|
class DtsGenerator{
|
||||||
public:
|
public:
|
||||||
DtsGenerator() = default;
|
DtsGenerator() = default;
|
||||||
@ -90,8 +102,6 @@ private:
|
|||||||
int _sorter_max_size = 0;
|
int _sorter_max_size = 0;
|
||||||
int _count_sorter_max_size = 0;
|
int _count_sorter_max_size = 0;
|
||||||
set<uint32_t> _pts_sorter;
|
set<uint32_t> _pts_sorter;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}//namespace mediakit
|
}//namespace mediakit
|
||||||
|
@ -50,6 +50,9 @@ void FlvMuxer::start(const EventPoller::Ptr &poller,const RtmpMediaSource::Ptr &
|
|||||||
}
|
}
|
||||||
strongSelf->onDetach();
|
strongSelf->onDetach();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//音频同步于视频
|
||||||
|
_stamp[0].makeRelation( _stamp[1]);
|
||||||
_ring_reader->setReadCB([weakSelf](const RtmpMediaSource::RingDataType &pkt){
|
_ring_reader->setReadCB([weakSelf](const RtmpMediaSource::RingDataType &pkt){
|
||||||
auto strongSelf = weakSelf.lock();
|
auto strongSelf = weakSelf.lock();
|
||||||
if(!strongSelf){
|
if(!strongSelf){
|
||||||
|
@ -266,6 +266,8 @@ void RtmpSession::sendPlayResponse(const string &err,const RtmpMediaSource::Ptr
|
|||||||
onSendMedia(pkt);
|
onSendMedia(pkt);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//音频同步于视频
|
||||||
|
_stamp[0].makeRelation( _stamp[1]);
|
||||||
_pRingReader = src->getRing()->attach(getPoller());
|
_pRingReader = src->getRing()->attach(getPoller());
|
||||||
weak_ptr<RtmpSession> weakSelf = dynamic_pointer_cast<RtmpSession>(shared_from_this());
|
weak_ptr<RtmpSession> weakSelf = dynamic_pointer_cast<RtmpSession>(shared_from_this());
|
||||||
_pRingReader->setReadCB([weakSelf](const RtmpMediaSource::RingDataType &pkt) {
|
_pRingReader->setReadCB([weakSelf](const RtmpMediaSource::RingDataType &pkt) {
|
||||||
|
Loading…
Reference in New Issue
Block a user