Commit 28262b15 by xiongziliang

优化性能

parent 16e21e02
...@@ -100,9 +100,8 @@ public: ...@@ -100,9 +100,8 @@ public:
* 设置metadata * 设置metadata
*/ */
virtual void setMetaData(const AMFValue &metadata) { virtual void setMetaData(const AMFValue &metadata) {
lock_guard<recursive_mutex> lock(_mtx);
_metadata = metadata; _metadata = metadata;
if(_ring){ if (_ring) {
regist(); regist();
} }
} }
...@@ -121,19 +120,19 @@ public: ...@@ -121,19 +120,19 @@ public:
* @param key 是否为关键帧 * @param key 是否为关键帧
*/ */
void onWrite(const RtmpPacket::Ptr &pkt, bool key = true) override { void onWrite(const RtmpPacket::Ptr &pkt, bool key = true) override {
lock_guard<recursive_mutex> lock(_mtx); //保存当前时间戳
if(pkt->type_id == MSG_VIDEO){ switch (pkt->type_id) {
//有视频,那么启用GOP缓存 case MSG_VIDEO : _track_stamps[TrackVideo] = pkt->time_stamp, _have_video = true; break;
_have_video = true; case MSG_AUDIO : _track_stamps[TrackAudio] = pkt->time_stamp; break;
default : break;
} }
if (pkt->isCfgFrame()) { if (pkt->isCfgFrame()) {
lock_guard<recursive_mutex> lock(_mtx);
_config_frame_map[pkt->type_id] = pkt; _config_frame_map[pkt->type_id] = pkt;
return; return;
} }
//保存当前时间戳
_track_stamps_map[pkt->type_id] = pkt->time_stamp;
if (!_ring) { if (!_ring) {
weak_ptr<RtmpMediaSource> weakSelf = dynamic_pointer_cast<RtmpMediaSource>(shared_from_this()); weak_ptr<RtmpMediaSource> weakSelf = dynamic_pointer_cast<RtmpMediaSource>(shared_from_this());
auto lam = [weakSelf](const EventPoller::Ptr &, int size, bool) { auto lam = [weakSelf](const EventPoller::Ptr &, int size, bool) {
...@@ -144,9 +143,8 @@ public: ...@@ -144,9 +143,8 @@ public:
strongSelf->onReaderChanged(size); strongSelf->onReaderChanged(size);
}; };
//rtmp包缓存最大允许512个,如果是纯视频(25fps)大概为20秒数据 //GOP默认缓冲512组RTMP包,每组RTMP包时间戳相同(如果开启合并写了,那么每组为合并写时间内的RTMP包),
//但是这个是GOP缓存的上限值,真实的GOP缓存大小等于两个I帧之间的包数的两倍 //每次遇到关键帧第一个RTMP包,则会清空GOP缓存(因为有新的关键帧了,同样可以实现秒开)
//而且每次遇到I帧,则会清空GOP缓存,所以真实的GOP缓存远小于此值
_ring = std::make_shared<RingType>(_ring_size,std::move(lam)); _ring = std::make_shared<RingType>(_ring_size,std::move(lam));
onReaderChanged(0); onReaderChanged(0);
...@@ -161,19 +159,23 @@ public: ...@@ -161,19 +159,23 @@ public:
* 获取当前时间戳 * 获取当前时间戳
*/ */
uint32_t getTimeStamp(TrackType trackType) override { uint32_t getTimeStamp(TrackType trackType) override {
lock_guard<recursive_mutex> lock(_mtx); assert(trackType >= TrackInvalid && trackType < TrackMax);
switch (trackType) { if (trackType != TrackInvalid) {
case TrackVideo: //获取某track的时间戳
return _track_stamps_map[MSG_VIDEO]; return _track_stamps[trackType];
case TrackAudio: }
return _track_stamps_map[MSG_AUDIO];
default: //获取所有track的最小时间戳
return MAX(_track_stamps_map[MSG_VIDEO], _track_stamps_map[MSG_AUDIO]); uint32_t ret = UINT32_MAX;
for (auto &stamp : _track_stamps) {
if (stamp > 0 && stamp < ret) {
ret = stamp;
}
} }
return ret;
} }
private: private:
/** /**
* 批量flush rtmp包时触发该函数 * 批量flush rtmp包时触发该函数
* @param rtmp_list rtmp包列表 * @param rtmp_list rtmp包列表
...@@ -194,12 +196,13 @@ private: ...@@ -194,12 +196,13 @@ private:
} }
private: private:
int _ring_size;
bool _have_video = false; bool _have_video = false;
mutable recursive_mutex _mtx; int _ring_size;
uint32_t _track_stamps[TrackMax] = {0};
AMFValue _metadata; AMFValue _metadata;
RingType::Ptr _ring; RingType::Ptr _ring;
unordered_map<int, uint32_t> _track_stamps_map;
mutable recursive_mutex _mtx;
unordered_map<int, RtmpPacket::Ptr> _config_frame_map; unordered_map<int, RtmpPacket::Ptr> _config_frame_map;
}; };
......
...@@ -83,7 +83,8 @@ public: ...@@ -83,7 +83,8 @@ public:
* 获取相应轨道的ssrc * 获取相应轨道的ssrc
*/ */
virtual uint32_t getSsrc(TrackType trackType) { virtual uint32_t getSsrc(TrackType trackType) {
auto track = _sdp_parser.getTrack(trackType); assert(trackType >= 0 && trackType < TrackMax);
auto track = _tracks[trackType];
if (!track) { if (!track) {
return 0; return 0;
} }
...@@ -94,7 +95,8 @@ public: ...@@ -94,7 +95,8 @@ public:
* 获取相应轨道的seqence * 获取相应轨道的seqence
*/ */
virtual uint16_t getSeqence(TrackType trackType) { virtual uint16_t getSeqence(TrackType trackType) {
auto track = _sdp_parser.getTrack(trackType); assert(trackType >= 0 && trackType < TrackMax);
auto track = _tracks[trackType];
if (!track) { if (!track) {
return 0; return 0;
} }
...@@ -105,28 +107,33 @@ public: ...@@ -105,28 +107,33 @@ public:
* 获取相应轨道的时间戳,单位毫秒 * 获取相应轨道的时间戳,单位毫秒
*/ */
uint32_t getTimeStamp(TrackType trackType) override { uint32_t getTimeStamp(TrackType trackType) override {
auto track = _sdp_parser.getTrack(trackType); assert(trackType >= TrackInvalid && trackType < TrackMax);
if (track) { if (trackType != TrackInvalid) {
return track->_time_stamp; //获取某track的时间戳
auto track = _tracks[trackType];
if (track) {
return track->_time_stamp;
}
} }
auto tracks = _sdp_parser.getAvailableTrack();
switch (tracks.size()) { //获取所有track的最小时间戳
case 0: uint32_t ret = UINT32_MAX;
return 0; for (auto &track : _tracks) {
case 1: if (track && track->_time_stamp < ret) {
return tracks[0]->_time_stamp; ret = track->_time_stamp;
default: }
return MIN(tracks[0]->_time_stamp, tracks[1]->_time_stamp);
} }
return ret;
} }
/** /**
* 更新时间戳 * 更新时间戳
*/ */
void setTimeStamp(uint32_t uiStamp) override { void setTimeStamp(uint32_t stamp) override {
auto tracks = _sdp_parser.getAvailableTrack(); for (auto &track : _tracks) {
for (auto &track : tracks) { if (track) {
track->_time_stamp = uiStamp; track->_time_stamp = stamp;
}
} }
} }
...@@ -135,8 +142,10 @@ public: ...@@ -135,8 +142,10 @@ public:
*/ */
virtual void setSdp(const string &sdp) { virtual void setSdp(const string &sdp) {
_sdp = sdp; _sdp = sdp;
_sdp_parser.load(sdp); SdpParser sdp_parser(sdp);
_have_video = (bool)_sdp_parser.getTrack(TrackVideo); _tracks[TrackVideo] = sdp_parser.getTrack(TrackVideo);
_tracks[TrackAudio] = sdp_parser.getTrack(TrackAudio);
_have_video = (bool) _tracks[TrackVideo];
if (_ring) { if (_ring) {
regist(); regist();
} }
...@@ -148,7 +157,8 @@ public: ...@@ -148,7 +157,8 @@ public:
* @param keyPos 该包是否为关键帧的第一个包 * @param keyPos 该包是否为关键帧的第一个包
*/ */
void onWrite(const RtpPacket::Ptr &rtp, bool keyPos) override { void onWrite(const RtpPacket::Ptr &rtp, bool keyPos) override {
auto track = _sdp_parser.getTrack(rtp->type); assert(rtp->type >= 0 && rtp->type < TrackMax);
auto track = _tracks[rtp->type];
if (track) { if (track) {
track->_seq = rtp->sequence; track->_seq = rtp->sequence;
track->_time_stamp = rtp->timeStamp; track->_time_stamp = rtp->timeStamp;
...@@ -163,9 +173,8 @@ public: ...@@ -163,9 +173,8 @@ public:
} }
strongSelf->onReaderChanged(size); strongSelf->onReaderChanged(size);
}; };
//rtp包缓存最大允许2048个,大概最多3MB数据 //GOP默认缓冲512组RTP包,每组RTP包时间戳相同(如果开启合并写了,那么每组为合并写时间内的RTP包),
//但是这个是GOP缓存的上限值,真实的GOP缓存大小等于两个I帧之间的包数的两倍 //每次遇到关键帧第一个RTP包,则会清空GOP缓存(因为有新的关键帧了,同样可以实现秒开)
//而且每次遇到I帧,则会清空GOP缓存,所以真实的GOP缓存远小于此值
_ring = std::make_shared<RingType>(_ring_size, std::move(lam)); _ring = std::make_shared<RingType>(_ring_size, std::move(lam));
onReaderChanged(0); onReaderChanged(0);
if (!_sdp.empty()) { if (!_sdp.empty()) {
...@@ -176,7 +185,6 @@ public: ...@@ -176,7 +185,6 @@ public:
} }
private: private:
/** /**
* 批量flush rtp包时触发该函数 * 批量flush rtp包时触发该函数
* @param rtp_list rtp包列表 * @param rtp_list rtp包列表
...@@ -195,12 +203,13 @@ private: ...@@ -195,12 +203,13 @@ private:
onNoneReader(); onNoneReader();
} }
} }
private: private:
int _ring_size;
bool _have_video = false; bool _have_video = false;
SdpParser _sdp_parser; int _ring_size;
string _sdp; string _sdp;
RingType::Ptr _ring; RingType::Ptr _ring;
SdpTrack::Ptr _tracks[TrackMax];
}; };
} /* namespace mediakit */ } /* namespace mediakit */
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论