diff --git a/src/MediaFile/Stamp.cpp b/src/MediaFile/Stamp.cpp index d4b67df9..02941be2 100644 --- a/src/MediaFile/Stamp.cpp +++ b/src/MediaFile/Stamp.cpp @@ -29,15 +29,21 @@ namespace mediakit { 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){ //记录第一次时间戳,后面好计算时间戳增量 _start_dts = dts; _first = false; _ticker = std::make_shared(); } - //pts和dts的差值 - int pts_dts_diff = pts - dts; - if(_modifyStamp){ + if (!dts) { + //没有解码时间戳,我们生成解码时间戳 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; //////////////以下是播放时间戳的计算////////////////// - if(!pts){ - //没有播放时间戳 - pts = dts; - } - if(pts_dts_diff > 200 || pts_dts_diff < -200){ //如果差值大于200毫秒,则认为由于回环导致时间戳错乱了 pts_dts_diff = 0; diff --git a/src/MediaFile/Stamp.h b/src/MediaFile/Stamp.h index e6b2d3b2..3eed2a1d 100644 --- a/src/MediaFile/Stamp.h +++ b/src/MediaFile/Stamp.h @@ -33,16 +33,17 @@ using namespace toolkit; namespace mediakit { +//该类解决时间戳回环、回退问题 +//计算相对时间戳或者产生平滑时间戳 class Stamp { public: - Stamp(bool modifyStamp = false) {_modifyStamp = modifyStamp;}; + Stamp() = default; ~Stamp() = default; void revise(uint32_t dts, uint32_t pts, int64_t &dts_out, int64_t &pts_out); private: int64_t _start_dts = 0; int64_t _dts_inc = 0; bool _first = true; - bool _modifyStamp; std::shared_ptr _ticker; }; diff --git a/src/Rtmp/RtmpSession.cpp b/src/Rtmp/RtmpSession.cpp index 10f76773..01251224 100644 --- a/src/Rtmp/RtmpSession.cpp +++ b/src/Rtmp/RtmpSession.cpp @@ -397,20 +397,20 @@ void RtmpSession::setMetaData(AMFDecoder &dec) { void RtmpSession::onProcessCmd(AMFDecoder &dec) { typedef void (RtmpSession::*rtmpCMDHandle)(AMFDecoder &dec); - static unordered_map g_mapCmd; + static unordered_map s_cmd_functions; static onceToken token([]() { - g_mapCmd.emplace("connect",&RtmpSession::onCmd_connect); - g_mapCmd.emplace("createStream",&RtmpSession::onCmd_createStream); - g_mapCmd.emplace("publish",&RtmpSession::onCmd_publish); - g_mapCmd.emplace("deleteStream",&RtmpSession::onCmd_deleteStream); - g_mapCmd.emplace("play",&RtmpSession::onCmd_play); - g_mapCmd.emplace("play2",&RtmpSession::onCmd_play2); - g_mapCmd.emplace("seek",&RtmpSession::onCmd_seek); - g_mapCmd.emplace("pause",&RtmpSession::onCmd_pause);}, []() {}); + s_cmd_functions.emplace("connect",&RtmpSession::onCmd_connect); + s_cmd_functions.emplace("createStream",&RtmpSession::onCmd_createStream); + s_cmd_functions.emplace("publish",&RtmpSession::onCmd_publish); + s_cmd_functions.emplace("deleteStream",&RtmpSession::onCmd_deleteStream); + s_cmd_functions.emplace("play",&RtmpSession::onCmd_play); + s_cmd_functions.emplace("play2",&RtmpSession::onCmd_play2); + s_cmd_functions.emplace("seek",&RtmpSession::onCmd_seek); + s_cmd_functions.emplace("pause",&RtmpSession::onCmd_pause);}, []() {}); std::string method = dec.load(); - auto it = g_mapCmd.find(method); - if (it == g_mapCmd.end()) { + auto it = s_cmd_functions.find(method); + if (it == s_cmd_functions.end()) { TraceP(this) << "can not support cmd:" << method; return; } @@ -444,10 +444,12 @@ void RtmpSession::onRtmpChunk(RtmpPacket &chunkData) { throw std::runtime_error("Not a rtmp publisher!"); } GET_CONFIG(bool,rtmp_modify_stamp,Rtmp::kModifyStamp); - if(rtmp_modify_stamp){ - chunkData.timeStamp = _stampTicker[chunkData.typeId % 2].elapsedTime(); - } - _pPublisherSrc->onWrite(std::make_shared(std::move(chunkData))); + if(rtmp_modify_stamp){ + int64_t dts_out; + _stamp[chunkData.typeId % 2].revise(0, 0, dts_out, dts_out); + chunkData.timeStamp = dts_out; + } + _pPublisherSrc->onWrite(std::make_shared(std::move(chunkData))); } break; default: @@ -473,20 +475,10 @@ void RtmpSession::onCmd_seek(AMFDecoder &dec) { } void RtmpSession::onSendMedia(const RtmpPacket::Ptr &pkt) { - auto modifiedStamp = pkt->timeStamp; - auto &firstStamp = _aui32FirstStamp[pkt->typeId % 2]; - if(!firstStamp){ - firstStamp = modifiedStamp; - } - if(modifiedStamp >= firstStamp){ - //计算时间戳增量 - modifiedStamp -= firstStamp; - }else{ - //发生回环,重新计算时间戳增量 - CLEAR_ARR(_aui32FirstStamp); - modifiedStamp = 0; - } - sendRtmp(pkt->typeId, pkt->streamId, pkt, modifiedStamp, pkt->chunkId); + //rtmp播放器时间戳从零开始 + int64_t dts_out; + _stamp[pkt->typeId % 2].revise(pkt->timeStamp, 0, dts_out, dts_out); + sendRtmp(pkt->typeId, pkt->streamId, pkt, dts_out, pkt->chunkId); } diff --git a/src/Rtmp/RtmpSession.h b/src/Rtmp/RtmpSession.h index c6f1d858..fbb8cf38 100644 --- a/src/Rtmp/RtmpSession.h +++ b/src/Rtmp/RtmpSession.h @@ -37,6 +37,8 @@ #include "Util/util.h" #include "Util/TimeTicker.h" #include "Network/TcpSession.h" +#include "MediaFile/Stamp.h" + using namespace toolkit; namespace mediakit { @@ -88,11 +90,11 @@ private: MediaInfo _mediaInfo; double _dNowReqID = 0; Ticker _ticker;//数据接收时间 - SmoothTicker _stampTicker[2];//时间戳生产器 RingBuffer::RingReader::Ptr _pRingReader; std::shared_ptr _pPublisherSrc; std::weak_ptr _pPlayerSrc; - uint32_t _aui32FirstStamp[2] = {0}; + //时间戳修整器 + Stamp _stamp[2]; //消耗的总流量 uint64_t _ui64TotalBytes = 0;