mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-26 20:47:08 +08:00
优化rtmp时间戳修正
This commit is contained in:
parent
7f0fa0ead1
commit
fc0544512b
@ -29,15 +29,21 @@
|
|||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
void Stamp::revise(uint32_t dts, uint32_t pts, int64_t &dts_out, int64_t &pts_out) {
|
void Stamp::revise(uint32_t dts, uint32_t pts, int64_t &dts_out, int64_t &pts_out) {
|
||||||
|
if(!pts){
|
||||||
|
//没有播放时间戳,使其赋值为解码时间戳
|
||||||
|
pts = dts;
|
||||||
|
}
|
||||||
|
//pts和dts的差值
|
||||||
|
int pts_dts_diff = pts - dts;
|
||||||
|
|
||||||
if(_first){
|
if(_first){
|
||||||
//记录第一次时间戳,后面好计算时间戳增量
|
//记录第一次时间戳,后面好计算时间戳增量
|
||||||
_start_dts = dts;
|
_start_dts = dts;
|
||||||
_first = false;
|
_first = false;
|
||||||
_ticker = std::make_shared<SmoothTicker>();
|
_ticker = std::make_shared<SmoothTicker>();
|
||||||
}
|
}
|
||||||
//pts和dts的差值
|
if (!dts) {
|
||||||
int pts_dts_diff = pts - dts;
|
//没有解码时间戳,我们生成解码时间戳
|
||||||
if(_modifyStamp){
|
|
||||||
dts = _ticker->elapsedTime();
|
dts = _ticker->elapsedTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,11 +66,6 @@ void Stamp::revise(uint32_t dts, uint32_t pts, int64_t &dts_out, int64_t &pts_ou
|
|||||||
_dts_inc = dts_out;
|
_dts_inc = dts_out;
|
||||||
|
|
||||||
//////////////以下是播放时间戳的计算//////////////////
|
//////////////以下是播放时间戳的计算//////////////////
|
||||||
if(!pts){
|
|
||||||
//没有播放时间戳
|
|
||||||
pts = dts;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pts_dts_diff > 200 || pts_dts_diff < -200){
|
if(pts_dts_diff > 200 || pts_dts_diff < -200){
|
||||||
//如果差值大于200毫秒,则认为由于回环导致时间戳错乱了
|
//如果差值大于200毫秒,则认为由于回环导致时间戳错乱了
|
||||||
pts_dts_diff = 0;
|
pts_dts_diff = 0;
|
||||||
|
@ -33,16 +33,17 @@ using namespace toolkit;
|
|||||||
|
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
|
//该类解决时间戳回环、回退问题
|
||||||
|
//计算相对时间戳或者产生平滑时间戳
|
||||||
class Stamp {
|
class Stamp {
|
||||||
public:
|
public:
|
||||||
Stamp(bool modifyStamp = false) {_modifyStamp = modifyStamp;};
|
Stamp() = default;
|
||||||
~Stamp() = default;
|
~Stamp() = default;
|
||||||
void revise(uint32_t dts, uint32_t pts, int64_t &dts_out, int64_t &pts_out);
|
void revise(uint32_t dts, uint32_t pts, int64_t &dts_out, int64_t &pts_out);
|
||||||
private:
|
private:
|
||||||
int64_t _start_dts = 0;
|
int64_t _start_dts = 0;
|
||||||
int64_t _dts_inc = 0;
|
int64_t _dts_inc = 0;
|
||||||
bool _first = true;
|
bool _first = true;
|
||||||
bool _modifyStamp;
|
|
||||||
std::shared_ptr<SmoothTicker> _ticker;
|
std::shared_ptr<SmoothTicker> _ticker;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -397,20 +397,20 @@ void RtmpSession::setMetaData(AMFDecoder &dec) {
|
|||||||
|
|
||||||
void RtmpSession::onProcessCmd(AMFDecoder &dec) {
|
void RtmpSession::onProcessCmd(AMFDecoder &dec) {
|
||||||
typedef void (RtmpSession::*rtmpCMDHandle)(AMFDecoder &dec);
|
typedef void (RtmpSession::*rtmpCMDHandle)(AMFDecoder &dec);
|
||||||
static unordered_map<string, rtmpCMDHandle> g_mapCmd;
|
static unordered_map<string, rtmpCMDHandle> s_cmd_functions;
|
||||||
static onceToken token([]() {
|
static onceToken token([]() {
|
||||||
g_mapCmd.emplace("connect",&RtmpSession::onCmd_connect);
|
s_cmd_functions.emplace("connect",&RtmpSession::onCmd_connect);
|
||||||
g_mapCmd.emplace("createStream",&RtmpSession::onCmd_createStream);
|
s_cmd_functions.emplace("createStream",&RtmpSession::onCmd_createStream);
|
||||||
g_mapCmd.emplace("publish",&RtmpSession::onCmd_publish);
|
s_cmd_functions.emplace("publish",&RtmpSession::onCmd_publish);
|
||||||
g_mapCmd.emplace("deleteStream",&RtmpSession::onCmd_deleteStream);
|
s_cmd_functions.emplace("deleteStream",&RtmpSession::onCmd_deleteStream);
|
||||||
g_mapCmd.emplace("play",&RtmpSession::onCmd_play);
|
s_cmd_functions.emplace("play",&RtmpSession::onCmd_play);
|
||||||
g_mapCmd.emplace("play2",&RtmpSession::onCmd_play2);
|
s_cmd_functions.emplace("play2",&RtmpSession::onCmd_play2);
|
||||||
g_mapCmd.emplace("seek",&RtmpSession::onCmd_seek);
|
s_cmd_functions.emplace("seek",&RtmpSession::onCmd_seek);
|
||||||
g_mapCmd.emplace("pause",&RtmpSession::onCmd_pause);}, []() {});
|
s_cmd_functions.emplace("pause",&RtmpSession::onCmd_pause);}, []() {});
|
||||||
|
|
||||||
std::string method = dec.load<std::string>();
|
std::string method = dec.load<std::string>();
|
||||||
auto it = g_mapCmd.find(method);
|
auto it = s_cmd_functions.find(method);
|
||||||
if (it == g_mapCmd.end()) {
|
if (it == s_cmd_functions.end()) {
|
||||||
TraceP(this) << "can not support cmd:" << method;
|
TraceP(this) << "can not support cmd:" << method;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -445,7 +445,9 @@ void RtmpSession::onRtmpChunk(RtmpPacket &chunkData) {
|
|||||||
}
|
}
|
||||||
GET_CONFIG(bool,rtmp_modify_stamp,Rtmp::kModifyStamp);
|
GET_CONFIG(bool,rtmp_modify_stamp,Rtmp::kModifyStamp);
|
||||||
if(rtmp_modify_stamp){
|
if(rtmp_modify_stamp){
|
||||||
chunkData.timeStamp = _stampTicker[chunkData.typeId % 2].elapsedTime();
|
int64_t dts_out;
|
||||||
|
_stamp[chunkData.typeId % 2].revise(0, 0, dts_out, dts_out);
|
||||||
|
chunkData.timeStamp = dts_out;
|
||||||
}
|
}
|
||||||
_pPublisherSrc->onWrite(std::make_shared<RtmpPacket>(std::move(chunkData)));
|
_pPublisherSrc->onWrite(std::make_shared<RtmpPacket>(std::move(chunkData)));
|
||||||
}
|
}
|
||||||
@ -473,20 +475,10 @@ void RtmpSession::onCmd_seek(AMFDecoder &dec) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RtmpSession::onSendMedia(const RtmpPacket::Ptr &pkt) {
|
void RtmpSession::onSendMedia(const RtmpPacket::Ptr &pkt) {
|
||||||
auto modifiedStamp = pkt->timeStamp;
|
//rtmp播放器时间戳从零开始
|
||||||
auto &firstStamp = _aui32FirstStamp[pkt->typeId % 2];
|
int64_t dts_out;
|
||||||
if(!firstStamp){
|
_stamp[pkt->typeId % 2].revise(pkt->timeStamp, 0, dts_out, dts_out);
|
||||||
firstStamp = modifiedStamp;
|
sendRtmp(pkt->typeId, pkt->streamId, pkt, dts_out, pkt->chunkId);
|
||||||
}
|
|
||||||
if(modifiedStamp >= firstStamp){
|
|
||||||
//计算时间戳增量
|
|
||||||
modifiedStamp -= firstStamp;
|
|
||||||
}else{
|
|
||||||
//发生回环,重新计算时间戳增量
|
|
||||||
CLEAR_ARR(_aui32FirstStamp);
|
|
||||||
modifiedStamp = 0;
|
|
||||||
}
|
|
||||||
sendRtmp(pkt->typeId, pkt->streamId, pkt, modifiedStamp, pkt->chunkId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,6 +37,8 @@
|
|||||||
#include "Util/util.h"
|
#include "Util/util.h"
|
||||||
#include "Util/TimeTicker.h"
|
#include "Util/TimeTicker.h"
|
||||||
#include "Network/TcpSession.h"
|
#include "Network/TcpSession.h"
|
||||||
|
#include "MediaFile/Stamp.h"
|
||||||
|
|
||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
|
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
@ -88,11 +90,11 @@ private:
|
|||||||
MediaInfo _mediaInfo;
|
MediaInfo _mediaInfo;
|
||||||
double _dNowReqID = 0;
|
double _dNowReqID = 0;
|
||||||
Ticker _ticker;//数据接收时间
|
Ticker _ticker;//数据接收时间
|
||||||
SmoothTicker _stampTicker[2];//时间戳生产器
|
|
||||||
RingBuffer<RtmpPacket::Ptr>::RingReader::Ptr _pRingReader;
|
RingBuffer<RtmpPacket::Ptr>::RingReader::Ptr _pRingReader;
|
||||||
std::shared_ptr<RtmpMediaSource> _pPublisherSrc;
|
std::shared_ptr<RtmpMediaSource> _pPublisherSrc;
|
||||||
std::weak_ptr<RtmpMediaSource> _pPlayerSrc;
|
std::weak_ptr<RtmpMediaSource> _pPlayerSrc;
|
||||||
uint32_t _aui32FirstStamp[2] = {0};
|
//时间戳修整器
|
||||||
|
Stamp _stamp[2];
|
||||||
//消耗的总流量
|
//消耗的总流量
|
||||||
uint64_t _ui64TotalBytes = 0;
|
uint64_t _ui64TotalBytes = 0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user