diff --git a/src/Http/HlsPlayer.cpp b/src/Http/HlsPlayer.cpp index e401ad2b..07c6a3cd 100644 --- a/src/Http/HlsPlayer.cpp +++ b/src/Http/HlsPlayer.cpp @@ -275,6 +275,14 @@ void HlsDemuxer::start(const EventPoller::Ptr &poller, TrackListener *listener) }, poller); } +void HlsDemuxer::pushTask(std::function task) { + int64_t stamp = 0; + if (!_frame_cache.empty()) { + stamp = _frame_cache.back().first; + } + _frame_cache.emplace_back(std::make_pair(stamp, std::move(task))); +} + bool HlsDemuxer::inputFrame(const Frame::Ptr &frame) { //为了避免track准备时间过长, 因此在没准备好之前, 直接消费掉所有的帧 if (!_delegate.isAllTrackReady()) { @@ -287,12 +295,15 @@ bool HlsDemuxer::inputFrame(const Frame::Ptr &frame) { setPlayPosition(frame->dts()); } //根据时间戳缓存frame - _frame_cache.emplace(frame->dts(), Frame::getCacheAbleFrame(frame)); + auto cached_frame = Frame::getCacheAbleFrame(frame); + _frame_cache.emplace_back(std::make_pair(frame->dts(), [cached_frame, this]() { + _delegate.inputFrame(cached_frame); + })); if (getBufferMS() > 30 * 1000) { //缓存超过30秒,强制消费至15秒(减少延时或内存占用) while (getBufferMS() > 15 * 1000) { - _delegate.inputFrame(_frame_cache.begin()->second); + _frame_cache.begin()->second(); _frame_cache.erase(_frame_cache.begin()); } //接着播放缓存中最早的帧 @@ -332,7 +343,7 @@ void HlsDemuxer::onTick() { } //消费掉已经到期的帧 - _delegate.inputFrame(it->second); + it->second(); it = _frame_cache.erase(it); } } @@ -368,8 +379,13 @@ void HlsPlayerImp::onPlayResult(const SockException &ex) { void HlsPlayerImp::onShutdown(const SockException &ex) { if (_demuxer) { - PlayerImp::onShutdown(ex); - _demuxer = nullptr; + std::weak_ptr weak_self = static_pointer_cast(shared_from_this()); + static_pointer_cast(_demuxer)->pushTask([weak_self, ex]() { + auto strong_self = weak_self.lock(); + if (strong_self) { + strong_self->PlayerImp::onShutdown(ex); + } + }); } } diff --git a/src/Http/HlsPlayer.h b/src/Http/HlsPlayer.h index 75610dcb..7db6316b 100644 --- a/src/Http/HlsPlayer.h +++ b/src/Http/HlsPlayer.h @@ -34,6 +34,7 @@ public: void addTrackCompleted() override { _delegate.addTrackCompleted(); } void resetTracks() override { ((MediaSink &)_delegate).resetTracks(); } std::vector getTracks(bool ready = true) const override { return _delegate.getTracks(ready); } + void pushTask(std::function task); private: void onTick(); @@ -46,7 +47,7 @@ private: toolkit::Ticker _ticker; toolkit::Timer::Ptr _timer; MediaSinkDelegate _delegate; - std::multimap _frame_cache; + std::deque > > _frame_cache; }; class HlsPlayer : public HttpClientImp , public PlayerBase , public HlsParser{ diff --git a/src/Http/TsplayerImp.cpp b/src/Http/TsplayerImp.cpp index c41abb97..6d6d1c17 100644 --- a/src/Http/TsplayerImp.cpp +++ b/src/Http/TsplayerImp.cpp @@ -45,8 +45,15 @@ void TsPlayerImp::onPlayResult(const SockException &ex) { } void TsPlayerImp::onShutdown(const SockException &ex) { - PlayerImp::onShutdown(ex); - _demuxer = nullptr; + if (_demuxer) { + std::weak_ptr weak_self = static_pointer_cast(shared_from_this()); + static_pointer_cast(_demuxer)->pushTask([weak_self, ex]() { + auto strong_self = weak_self.lock(); + if (strong_self) { + strong_self->PlayerImp::onShutdown(ex); + } + }); + } } vector TsPlayerImp::getTracks(bool ready) const {