hls/http-ts播放器在消费完frame时再触发shutdown事件

This commit is contained in:
xiongziliang 2022-05-13 23:22:00 +08:00
parent d8b99101cf
commit fdbfccb32e
3 changed files with 32 additions and 8 deletions

View File

@ -275,6 +275,14 @@ void HlsDemuxer::start(const EventPoller::Ptr &poller, TrackListener *listener)
}, poller);
}
void HlsDemuxer::pushTask(std::function<void()> 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<HlsPlayer, PlayerBase>::onShutdown(ex);
_demuxer = nullptr;
std::weak_ptr<HlsPlayerImp> weak_self = static_pointer_cast<HlsPlayerImp>(shared_from_this());
static_pointer_cast<HlsDemuxer>(_demuxer)->pushTask([weak_self, ex]() {
auto strong_self = weak_self.lock();
if (strong_self) {
strong_self->PlayerImp<HlsPlayer, PlayerBase>::onShutdown(ex);
}
});
}
}

View File

@ -34,6 +34,7 @@ public:
void addTrackCompleted() override { _delegate.addTrackCompleted(); }
void resetTracks() override { ((MediaSink &)_delegate).resetTracks(); }
std::vector<Track::Ptr> getTracks(bool ready = true) const override { return _delegate.getTracks(ready); }
void pushTask(std::function<void()> task);
private:
void onTick();
@ -46,7 +47,7 @@ private:
toolkit::Ticker _ticker;
toolkit::Timer::Ptr _timer;
MediaSinkDelegate _delegate;
std::multimap<int64_t, Frame::Ptr> _frame_cache;
std::deque<std::pair<int64_t, std::function<void()> > > _frame_cache;
};
class HlsPlayer : public HttpClientImp , public PlayerBase , public HlsParser{

View File

@ -45,8 +45,15 @@ void TsPlayerImp::onPlayResult(const SockException &ex) {
}
void TsPlayerImp::onShutdown(const SockException &ex) {
PlayerImp<TsPlayer, PlayerBase>::onShutdown(ex);
_demuxer = nullptr;
if (_demuxer) {
std::weak_ptr<TsPlayerImp> weak_self = static_pointer_cast<TsPlayerImp>(shared_from_this());
static_pointer_cast<HlsDemuxer>(_demuxer)->pushTask([weak_self, ex]() {
auto strong_self = weak_self.lock();
if (strong_self) {
strong_self->PlayerImp<TsPlayer, PlayerBase>::onShutdown(ex);
}
});
}
}
vector<Track::Ptr> TsPlayerImp::getTracks(bool ready) const {