diff --git a/conf/config.ini b/conf/config.ini index d87c9547..78abb92d 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -18,7 +18,6 @@ snap=%s -i %s -y -f mjpeg -t 0.001 %s #可以为相对(相对于本可执行程序目录)或绝对路径 log=./ffmpeg/ffmpeg.log - [general] #是否启用虚拟主机 enableVhost=0 @@ -48,6 +47,11 @@ publishToMP4=0 #合并写缓存大小(单位毫秒),合并写指服务器缓存一定的数据后才会一次性写入socket,这样能提高性能,但是会提高延时 #开启后会同时关闭TCP_NODELAY并开启MSG_MORE mergeWriteMS=0 +#全局的时间戳覆盖开关,在转协议时,对frame进行时间戳覆盖 +#该开关对rtsp/rtmp/rtp推流、rtsp/rtmp/hls拉流代理转协议时生效 +#会直接影响rtsp/rtmp/hls/mp4/flv等协议的时间戳 +#同协议情况下不影响(例如rtsp/rtmp推流,那么播放rtsp/rtmp时不会影响时间戳) +modifyStamp=0 [hls] #hls写文件的buf大小,调整参数可以提高文件io性能 diff --git a/src/Common/MultiMediaSourceMuxer.cpp b/src/Common/MultiMediaSourceMuxer.cpp index 58217d2b..70a20413 100644 --- a/src/Common/MultiMediaSourceMuxer.cpp +++ b/src/Common/MultiMediaSourceMuxer.cpp @@ -298,8 +298,69 @@ void MultiMediaSourceMuxer::resetTracks() { _muxer->resetTracks(); } +//该类实现frame级别的时间戳覆盖 +class FrameModifyStamp : public Frame{ +public: + typedef std::shared_ptr Ptr; + FrameModifyStamp(const Frame::Ptr &frame, Stamp &stamp){ + _frame = frame; + //覆盖时间戳 + stamp.revise(frame->dts(), frame->pts(), _dts, _pts, true); + } + ~FrameModifyStamp() override {} + + uint32_t dts() const override{ + return _dts; + } + + uint32_t pts() const override{ + return _pts; + } + + uint32_t prefixSize() const override { + return _frame->prefixSize(); + } + + bool keyFrame() const override { + return _frame->keyFrame(); + } + + bool configFrame() const override { + return _frame->configFrame(); + } + + bool cacheAble() const override { + return _frame->cacheAble(); + } + + char *data() const override { + return _frame->data(); + } + + uint32_t size() const override { + return _frame->size(); + } + + CodecId getCodecId() const override { + return _frame->getCodecId(); + } +private: + Frame::Ptr _frame; + int64_t _dts; + int64_t _pts; +}; + void MultiMediaSourceMuxer::inputFrame(const Frame::Ptr &frame) { - _muxer->inputFrame(frame); + GET_CONFIG(bool,modify_stamp,General::kModifyStamp); + if(!modify_stamp){ + //未开启时间戳覆盖 + _muxer->inputFrame(frame); + }else{ + //开启了时间戳覆盖 + FrameModifyStamp::Ptr new_frame = std::make_shared(frame,_stamp[frame->getTrackType()]); + //输入时间戳覆盖后的帧 + _muxer->inputFrame(new_frame); + } } bool MultiMediaSourceMuxer::isEnabled(){ diff --git a/src/Common/MultiMediaSourceMuxer.h b/src/Common/MultiMediaSourceMuxer.h index 04109745..2ba2aa99 100644 --- a/src/Common/MultiMediaSourceMuxer.h +++ b/src/Common/MultiMediaSourceMuxer.h @@ -178,6 +178,7 @@ public: private: MultiMuxerPrivate::Ptr _muxer; std::weak_ptr _listener; + Stamp _stamp[2]; }; }//namespace mediakit diff --git a/src/Common/config.cpp b/src/Common/config.cpp index 8a22bea1..d8f2b933 100644 --- a/src/Common/config.cpp +++ b/src/Common/config.cpp @@ -67,6 +67,7 @@ const string kPublishToRtxp = GENERAL_FIELD"publishToRtxp"; const string kPublishToHls = GENERAL_FIELD"publishToHls"; const string kPublishToMP4 = GENERAL_FIELD"publishToMP4"; const string kMergeWriteMS = GENERAL_FIELD"mergeWriteMS"; +const string kModifyStamp = GENERAL_FIELD"modifyStamp"; onceToken token([](){ mINI::Instance()[kFlowThreshold] = 1024; @@ -79,6 +80,7 @@ onceToken token([](){ mINI::Instance()[kPublishToHls] = 1; mINI::Instance()[kPublishToMP4] = 0; mINI::Instance()[kMergeWriteMS] = 0; + mINI::Instance()[kModifyStamp] = 0; },nullptr); }//namespace General diff --git a/src/Common/config.h b/src/Common/config.h index 3948879f..27b4cefa 100644 --- a/src/Common/config.h +++ b/src/Common/config.h @@ -174,6 +174,8 @@ extern const string kPublishToMP4 ; //合并写缓存大小(单位毫秒),合并写指服务器缓存一定的数据后才会一次性写入socket,这样能提高性能,但是会提高延时 //开启后会同时关闭TCP_NODELAY并开启MSG_MORE extern const string kMergeWriteMS ; +//全局的时间戳覆盖开关,在转协议时,对frame进行时间戳覆盖 +extern const string kModifyStamp; }//namespace General @@ -217,6 +219,7 @@ extern const string kDirectProxy; ////////////RTMP服务器配置/////////// namespace Rtmp { +//rtmp推流时间戳覆盖开关 extern const string kModifyStamp; //握手超时时间,默认15秒 extern const string kHandshakeSecond;