1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

HLS: Support reload HLS asynchronously. v5.0.172 v6.0.67 (#3782)

When reloading HLS, it directly operates unpublish and publish. At this
time, if HLS is pushed, an exception may occur.

The reason is that these two coroutines operated on the HLS object at
the same time, causing a null pointer.

Solution: Use asynchronous reload. During reload, only set variables and
let the message processing coroutine implement the reload.

---------

Co-authored-by: Haibo Chen <495810242@qq.com>
Co-authored-by: chundonglinlin <chundonglinlin@163.com>
This commit is contained in:
Winlin 2023-08-25 09:41:42 +08:00 committed by winlin
parent 6babf01de2
commit b5347e19f7
7 changed files with 112 additions and 61 deletions

View file

@ -1228,6 +1228,27 @@ srs_error_t SrsOriginHub::on_dvr_request_sh()
return err;
}
srs_error_t SrsOriginHub::on_hls_request_sh()
{
srs_error_t err = srs_success;
SrsSharedPtrMessage* cache_sh_video = source->meta->vsh();
if (cache_sh_video) {
if ((err = hls->on_video(cache_sh_video, source->meta->vsh_format())) != srs_success) {
return srs_error_wrap(err, "hls video");
}
}
SrsSharedPtrMessage* cache_sh_audio = source->meta->ash();
if (cache_sh_audio) {
if ((err = hls->on_audio(cache_sh_audio, source->meta->ash_format())) != srs_success) {
return srs_error_wrap(err, "hls audio");
}
}
return err;
}
srs_error_t SrsOriginHub::on_reload_vhost_forward(string vhost)
{
srs_error_t err = srs_success;
@ -1236,7 +1257,7 @@ srs_error_t SrsOriginHub::on_reload_vhost_forward(string vhost)
return err;
}
// TODO: FIXME: maybe should ignore when publish already stopped?
// TODO: FIXME: Must do async reload, see SrsHls::async_reload.
// forwarders
destroy_forwarders();
@ -1262,7 +1283,9 @@ srs_error_t SrsOriginHub::on_reload_vhost_dash(string vhost)
if (req_->vhost != vhost) {
return err;
}
// TODO: FIXME: Must do async reload, see SrsHls::async_reload.
dash->on_unpublish();
// Don't start DASH when source is not active.
@ -1306,47 +1329,8 @@ srs_error_t SrsOriginHub::on_reload_vhost_hls(string vhost)
if (req_->vhost != vhost) {
return err;
}
// TODO: FIXME: maybe should ignore when publish already stopped?
hls->on_unpublish();
// Don't start HLS when source is not active.
if (!is_active) {
return err;
}
if ((err = hls->on_publish()) != srs_success) {
return srs_error_wrap(err, "hls publish failed");
}
srs_trace("vhost %s hls reload success", vhost.c_str());
SrsRtmpFormat* format = source->format_;
// when publish, don't need to fetch sequence header, which is old and maybe corrupt.
// when reload, we must fetch the sequence header from source cache.
// notice the source to get the cached sequence header.
// when reload to start hls, hls will never get the sequence header in stream,
// use the SrsLiveSource.on_hls_start to push the sequence header to HLS.
SrsSharedPtrMessage* cache_sh_video = source->meta->vsh();
if (cache_sh_video) {
if ((err = format->on_video(cache_sh_video)) != srs_success) {
return srs_error_wrap(err, "format on_video");
}
if ((err = hls->on_video(cache_sh_video, format)) != srs_success) {
return srs_error_wrap(err, "hls on_video");
}
}
SrsSharedPtrMessage* cache_sh_audio = source->meta->ash();
if (cache_sh_audio) {
if ((err = format->on_audio(cache_sh_audio)) != srs_success) {
return srs_error_wrap(err, "format on_audio");
}
if ((err = hls->on_audio(cache_sh_audio, format)) != srs_success) {
return srs_error_wrap(err, "hls on_audio");
}
}
hls->async_reload();
return err;
}
@ -1358,8 +1342,8 @@ srs_error_t SrsOriginHub::on_reload_vhost_hds(string vhost)
if (req_->vhost != vhost) {
return err;
}
// TODO: FIXME: maybe should ignore when publish already stopped?
// TODO: FIXME: Must do async reload, see SrsHls::async_reload.
#ifdef SRS_HDS
hds->on_unpublish();
@ -1385,8 +1369,8 @@ srs_error_t SrsOriginHub::on_reload_vhost_dvr(string vhost)
if (req_->vhost != vhost) {
return err;
}
// TODO: FIXME: maybe should ignore when publish already stopped?
// TODO: FIXME: Must do async reload, see SrsHls::async_reload.
// cleanup dvr
dvr->on_unpublish();
@ -1422,8 +1406,8 @@ srs_error_t SrsOriginHub::on_reload_vhost_transcode(string vhost)
if (req_->vhost != vhost) {
return err;
}
// TODO: FIXME: maybe should ignore when publish already stopped?
// TODO: FIXME: Must do async reload, see SrsHls::async_reload.
encoder->on_unpublish();
@ -1447,8 +1431,8 @@ srs_error_t SrsOriginHub::on_reload_vhost_exec(string vhost)
if (req_->vhost != vhost) {
return err;
}
// TODO: FIXME: maybe should ignore when publish already stopped?
// TODO: FIXME: Must do async reload, see SrsHls::async_reload.
ng_exec->on_unpublish();