mirror of
https://github.com/ossrs/srs.git
synced 2025-02-15 04:42:04 +00:00
Merge branch 'develop' into 3.0release.srt.dev
This commit is contained in:
commit
f102a598b8
24 changed files with 276 additions and 63 deletions
|
@ -53,4 +53,6 @@ CONTRIBUTORS ordered by first contribution.
|
|||
* alphonsetai<tyh_123@163.com>
|
||||
* Michael.Ma<wnpllr@gmail.com>
|
||||
* lam2003<linmin3@yy.com>
|
||||
* runner365<shi.weibd@hotmail.com>
|
||||
* runner365<shi.weibd@hotmail.com>
|
||||
* XiaofengWang<wasphin@gmail.com>
|
||||
* XiaLixin<xialx@yuntongxun.com>
|
19
README.md
19
README.md
|
@ -153,6 +153,8 @@ For previous versions, please read:
|
|||
|
||||
## V4 changes
|
||||
|
||||
* v4.0, 2020-03-07, For [#1612][bug #1612], fix crash bug for RTSP. 4.0.12
|
||||
* v4.0, 2020-03-07, For [#1631][bug #1631], support sei_filter for SRT. 4.0.11
|
||||
* v4.0, 2020-03-01, For [#1621][bug #1621], support mix_correct for aggregate aac for SRT. 4.0.10
|
||||
* v4.0, 2020-02-25, For [#1615][bug #1615], support default app(live) for vmix SRT. 4.0.9
|
||||
* v4.0, 2020-02-21, For [#1598][bug #1598], support SLB health checking by TCP. 4.0.8
|
||||
|
@ -166,6 +168,12 @@ For previous versions, please read:
|
|||
|
||||
## V3 changes
|
||||
|
||||
* v3.0, 2020-03-12, For [#1630][bug #1630], disable cache for stream changing, and drop dup header. 3.0.128
|
||||
* v3.0, 2020-03-12, For [#1594][bug #1594], detect and disable daemon for docker. 3.0.127
|
||||
* v3.0, 2020-03-12, For [#1634][bug #1634], always check status in thread loop. 3.0.126
|
||||
* v3.0, 2020-03-11, For [#1634][bug #1634], refactor output with datetime for ingest/encoder/exec. 3.0.125
|
||||
* v3.0, 2020-03-11, For [#1634][bug #1634], fix quit by accident SIGTERM while killing FFMPEG. 3.0.124
|
||||
* <strong>v3.0, 2020-03-05, [3.0 beta2(3.0.123)][r3.0b2] released. 122170 lines.</strong>
|
||||
* v3.0, 2020-02-21, For [#1598][bug #1598], support SLB health checking by TCP. 3.0.123
|
||||
* v3.0, 2020-02-21, Fix bug for librtmp client ipv4/ipv6 socket. 3.0.122
|
||||
* v3.0, 2020-02-18, For [#1579][bug #1579], support start/final wait for gracefully quit. 3.0.121
|
||||
|
@ -765,6 +773,7 @@ For previous versions, please read:
|
|||
|
||||
## Releases
|
||||
|
||||
* 2020-03-05, [Release v3.0-b2][r3.0b2], 3.0 beta2, 3.0.123, 122170 lines.
|
||||
* 2020-02-14, [Release v3.0-b1][r3.0b1], 3.0 beta1, 3.0.117, 121964 lines.
|
||||
* 2020-02-02, [Release v3.0-b0][r3.0b0], 3.0 beta0, 3.0.112, 121709 lines.
|
||||
* 2020-01-21, [Release v3.0-a9][r3.0a9], 3.0 alpha9, 3.0.105, 121577 lines.
|
||||
|
@ -1689,10 +1698,18 @@ Winlin
|
|||
[bug #1598]: https://github.com/ossrs/srs/issues/1598
|
||||
[bug #1615]: https://github.com/ossrs/srs/issues/1615
|
||||
[bug #1621]: https://github.com/ossrs/srs/issues/1621
|
||||
[bug #xxxxxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxxxxx
|
||||
[bug #1634]: https://github.com/ossrs/srs/issues/1634
|
||||
[bug #1594]: https://github.com/ossrs/srs/issues/1594
|
||||
[bug #1630]: https://github.com/ossrs/srs/issues/1630
|
||||
[bug #yyyyyyyyyyyyy]: https://github.com/ossrs/srs/issues/yyyyyyyyyyyyy
|
||||
|
||||
[bug #1631]: https://github.com/ossrs/srs/issues/1631
|
||||
[bug #1612]: https://github.com/ossrs/srs/issues/1612
|
||||
[bug #zzzzzzzzzzzzz]: https://github.com/ossrs/srs/issues/zzzzzzzzzzzzz
|
||||
|
||||
[exo #828]: https://github.com/google/ExoPlayer/pull/828
|
||||
|
||||
[r3.0b2]: https://github.com/ossrs/srs/releases/tag/v3.0-b2
|
||||
[r3.0b1]: https://github.com/ossrs/srs/releases/tag/v3.0-b1
|
||||
[r3.0b0]: https://github.com/ossrs/srs/releases/tag/v3.0-b0
|
||||
[r3.0a9]: https://github.com/ossrs/srs/releases/tag/v3.0-a9
|
||||
|
|
|
@ -93,6 +93,10 @@ grace_final_wait 3200;
|
|||
# @see https://github.com/ossrs/srs/issues/1579#issuecomment-587475077
|
||||
# default: off
|
||||
force_grace_quit off;
|
||||
# Whether disable daemon for docker.
|
||||
# If on, it will set daemon to off in docker, even daemon is on.
|
||||
# default: on
|
||||
disable_daemon_for_docker on;
|
||||
|
||||
#############################################################################################
|
||||
# heartbeat/stats sections
|
||||
|
@ -1000,6 +1004,16 @@ vhost exec.srs.com {
|
|||
# [tcUrl] the client request tcUrl.
|
||||
# [swfUrl] the client request swfUrl.
|
||||
# [pageUrl] the client request pageUrl.
|
||||
# we also support datetime variables.
|
||||
# [2006], replace this const to current year.
|
||||
# [01], replace this const to current month.
|
||||
# [02], replace this const to current date.
|
||||
# [15], replace this const to current hour.
|
||||
# [04], replace this const to current minute.
|
||||
# [05], replace this const to current second.
|
||||
# [999], replace this const to current millisecond.
|
||||
# [timestamp],replace this const to current UNIX timestamp in ms.
|
||||
# @remark we use golang time format "2006-01-02 15:04:05.999" as "[2006]-[01]-[02]_[15].[04].[05]_[999]"
|
||||
# @remark empty to ignore this exec.
|
||||
publish ./objs/ffmpeg/bin/ffmpeg -f flv -i [url] -c copy -y ./[stream].flv;
|
||||
}
|
||||
|
@ -1353,6 +1367,16 @@ vhost ingest.srs.com {
|
|||
# output stream. variables:
|
||||
# [vhost] current vhost which start the ingest.
|
||||
# [port] system RTMP stream port.
|
||||
# we also support datetime variables.
|
||||
# [2006], replace this const to current year.
|
||||
# [01], replace this const to current month.
|
||||
# [02], replace this const to current date.
|
||||
# [15], replace this const to current hour.
|
||||
# [04], replace this const to current minute.
|
||||
# [05], replace this const to current second.
|
||||
# [999], replace this const to current millisecond.
|
||||
# [timestamp],replace this const to current UNIX timestamp in ms.
|
||||
# @remark we use golang time format "2006-01-02 15:04:05.999" as "[2006]-[01]-[02]_[15].[04].[05]_[999]"
|
||||
output rtmp://127.0.0.1:[port]/live?vhost=[vhost]/livestream;
|
||||
}
|
||||
}
|
||||
|
@ -1541,6 +1565,16 @@ vhost example.transcode.srs.com {
|
|||
# [app] the input stream app.
|
||||
# [stream] the input stream name.
|
||||
# [engine] the transcode engine name.
|
||||
# we also support datetime variables.
|
||||
# [2006], replace this const to current year.
|
||||
# [01], replace this const to current month.
|
||||
# [02], replace this const to current date.
|
||||
# [15], replace this const to current hour.
|
||||
# [04], replace this const to current minute.
|
||||
# [05], replace this const to current second.
|
||||
# [999], replace this const to current millisecond.
|
||||
# [timestamp],replace this const to current UNIX timestamp in ms.
|
||||
# @remark we use golang time format "2006-01-02 15:04:05.999" as "[2006]-[01]-[02]_[15].[04].[05]_[999]"
|
||||
output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine];
|
||||
}
|
||||
}
|
||||
|
|
1
trunk/configure
vendored
1
trunk/configure
vendored
|
@ -730,7 +730,6 @@ fi
|
|||
# next step
|
||||
#####################################################################################
|
||||
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
||||
ip=`ifconfig|grep "inet addr"| grep -v "127.0.0.1"|awk '{print $2}'|awk -F ':' 'NR==1 {print $2}'`
|
||||
echo ""
|
||||
echo "You can run 3rdparty applications:"
|
||||
if [ $SRS_HTTP_CALLBACK = YES ]; then
|
||||
|
|
|
@ -3489,7 +3489,7 @@ srs_error_t SrsConfig::check_normal_config()
|
|||
&& n != "http_server" && n != "stream_caster" && n != "srt_server"
|
||||
&& n != "utc_time" && n != "work_dir" && n != "asprocess"
|
||||
&& n != "ff_log_level" && n != "grace_final_wait" && n != "force_grace_quit"
|
||||
&& n != "grace_start_wait" && n != "empty_ip_ok"
|
||||
&& n != "grace_start_wait" && n != "empty_ip_ok" && n != "disable_daemon_for_docker"
|
||||
) {
|
||||
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal directive %s", n.c_str());
|
||||
}
|
||||
|
@ -4114,6 +4114,18 @@ bool SrsConfig::is_force_grace_quit()
|
|||
return SRS_CONF_PERFER_FALSE(conf->arg0());
|
||||
}
|
||||
|
||||
bool SrsConfig::disable_daemon_for_docker()
|
||||
{
|
||||
static bool DEFAULT = true;
|
||||
|
||||
SrsConfDirective* conf = root->get("disable_daemon_for_docker");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return SRS_CONF_PERFER_TRUE(conf->arg0());
|
||||
}
|
||||
|
||||
vector<SrsConfDirective*> SrsConfig::get_stream_casters()
|
||||
{
|
||||
srs_assert(root);
|
||||
|
|
|
@ -476,6 +476,8 @@ public:
|
|||
virtual srs_utime_t get_grace_final_wait();
|
||||
// Whether force to gracefully quit, never fast quit.
|
||||
virtual bool is_force_grace_quit();
|
||||
// Whether disable daemon for docker.
|
||||
virtual bool disable_daemon_for_docker();
|
||||
// stream_caster section
|
||||
public:
|
||||
// Get all stream_caster in config file.
|
||||
|
|
|
@ -234,15 +234,17 @@ srs_error_t SrsEdgeIngester::cycle()
|
|||
srs_error_t err = srs_success;
|
||||
|
||||
while (true) {
|
||||
// We always check status first.
|
||||
// @see https://github.com/ossrs/srs/issues/1634#issuecomment-597571561
|
||||
if ((err = trd->pull()) != srs_success) {
|
||||
return srs_error_wrap(err, "edge ingester");
|
||||
}
|
||||
|
||||
if ((err = do_cycle()) != srs_success) {
|
||||
srs_warn("EdgeIngester: Ignore error, %s", srs_error_desc(err).c_str());
|
||||
srs_freep(err);
|
||||
}
|
||||
|
||||
if ((err = trd->pull()) != srs_success) {
|
||||
return srs_error_wrap(err, "edge ingester");
|
||||
}
|
||||
|
||||
|
||||
srs_usleep(SRS_EDGE_INGESTER_CIMS);
|
||||
}
|
||||
|
||||
|
@ -314,7 +316,6 @@ srs_error_t SrsEdgeIngester::ingest(string& redirect)
|
|||
redirect = "";
|
||||
|
||||
while (true) {
|
||||
srs_error_t err = srs_success;
|
||||
if ((err = trd->pull()) != srs_success) {
|
||||
return srs_error_wrap(err, "thread quit");
|
||||
}
|
||||
|
@ -534,14 +535,16 @@ srs_error_t SrsEdgeForwarder::cycle()
|
|||
srs_error_t err = srs_success;
|
||||
|
||||
while (true) {
|
||||
if ((err = do_cycle()) != srs_success) {
|
||||
return srs_error_wrap(err, "do cycle");
|
||||
}
|
||||
|
||||
// We always check status first.
|
||||
// @see https://github.com/ossrs/srs/issues/1634#issuecomment-597571561
|
||||
if ((err = trd->pull()) != srs_success) {
|
||||
return srs_error_wrap(err, "thread pull");
|
||||
}
|
||||
|
||||
|
||||
if ((err = do_cycle()) != srs_success) {
|
||||
return srs_error_wrap(err, "do cycle");
|
||||
}
|
||||
|
||||
srs_usleep(SRS_EDGE_FORWARDER_CIMS);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ using namespace std;
|
|||
#include <srs_app_pithy_print.hpp>
|
||||
#include <srs_app_ffmpeg.hpp>
|
||||
#include <srs_kernel_utility.hpp>
|
||||
#include <srs_app_utility.hpp>
|
||||
|
||||
// for encoder to detect the dead loop
|
||||
static std::vector<std::string> _transcoded_url;
|
||||
|
@ -94,15 +95,17 @@ srs_error_t SrsEncoder::cycle()
|
|||
srs_error_t err = srs_success;
|
||||
|
||||
while (true) {
|
||||
if ((err = do_cycle()) != srs_success) {
|
||||
srs_warn("Encoder: Ignore error, %s", srs_error_desc(err).c_str());
|
||||
srs_error_reset(err);
|
||||
}
|
||||
|
||||
// We always check status first.
|
||||
// @see https://github.com/ossrs/srs/issues/1634#issuecomment-597571561
|
||||
if ((err = trd->pull()) != srs_success) {
|
||||
err = srs_error_wrap(err, "encoder");
|
||||
break;
|
||||
}
|
||||
|
||||
if ((err = do_cycle()) != srs_success) {
|
||||
srs_warn("Encoder: Ignore error, %s", srs_error_desc(err).c_str());
|
||||
srs_error_reset(err);
|
||||
}
|
||||
|
||||
srs_usleep(SRS_RTMP_ENCODER_CIMS);
|
||||
}
|
||||
|
@ -282,6 +285,7 @@ srs_error_t SrsEncoder::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsRequest* req, Sr
|
|||
output = srs_string_replace(output, "[stream]", req->stream);
|
||||
output = srs_string_replace(output, "[param]", req->param);
|
||||
output = srs_string_replace(output, "[engine]", engine->arg0());
|
||||
output = srs_path_build_timestamp(output);
|
||||
|
||||
std::string log_file = SRS_CONSTS_NULL_FILE; // disabled
|
||||
// write ffmpeg info to log file.
|
||||
|
|
|
@ -181,15 +181,17 @@ srs_error_t SrsForwarder::cycle()
|
|||
srs_error_t err = srs_success;
|
||||
|
||||
while (true) {
|
||||
// We always check status first.
|
||||
// @see https://github.com/ossrs/srs/issues/1634#issuecomment-597571561
|
||||
if ((err = trd->pull()) != srs_success) {
|
||||
return srs_error_wrap(err, "forwarder");
|
||||
}
|
||||
|
||||
if ((err = do_cycle()) != srs_success) {
|
||||
srs_warn("Forwarder: Ignore error, %s", srs_error_desc(err).c_str());
|
||||
srs_freep(err);
|
||||
}
|
||||
|
||||
if ((err = trd->pull()) != srs_success) {
|
||||
return srs_error_wrap(err, "forwarder");
|
||||
}
|
||||
|
||||
|
||||
srs_usleep(SRS_FORWARDER_CIMS);
|
||||
}
|
||||
|
||||
|
|
|
@ -646,13 +646,13 @@ srs_error_t SrsLiveStream::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMess
|
|||
// TODO: free and erase the disabled entry after all related connections is closed.
|
||||
// TODO: FXIME: Support timeout for player, quit infinite-loop.
|
||||
while (entry->enabled) {
|
||||
pprint->elapse();
|
||||
|
||||
// Whether client closed the FD.
|
||||
if ((err = trd->pull()) != srs_success) {
|
||||
return srs_error_wrap(err, "recv thread");
|
||||
}
|
||||
|
||||
pprint->elapse();
|
||||
|
||||
// get messages from consumer.
|
||||
// each msg in msgs.msgs must be free, for the SrsMessageArray never free them.
|
||||
int count = 0;
|
||||
|
|
|
@ -201,15 +201,17 @@ srs_error_t SrsIngester::cycle()
|
|||
srs_error_t err = srs_success;
|
||||
|
||||
while (!disposed) {
|
||||
// We always check status first.
|
||||
// @see https://github.com/ossrs/srs/issues/1634#issuecomment-597571561
|
||||
if ((err = trd->pull()) != srs_success) {
|
||||
return srs_error_wrap(err, "ingester");
|
||||
}
|
||||
|
||||
if ((err = do_cycle()) != srs_success) {
|
||||
srs_warn("Ingester: Ignore error, %s", srs_error_desc(err).c_str());
|
||||
srs_freep(err);
|
||||
}
|
||||
|
||||
if ((err = trd->pull()) != srs_success) {
|
||||
return srs_error_wrap(err, "ingester");
|
||||
}
|
||||
|
||||
|
||||
srs_usleep(SRS_AUTO_INGESTER_CIMS);
|
||||
}
|
||||
|
||||
|
@ -382,6 +384,7 @@ srs_error_t SrsIngester::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective*
|
|||
// ie. rtmp://localhost:1935/live/livestream_sd
|
||||
output = srs_string_replace(output, "[vhost]", vhost->arg0());
|
||||
output = srs_string_replace(output, "[port]", srs_int2str(port));
|
||||
output = srs_path_build_timestamp(output);
|
||||
if (output.empty()) {
|
||||
return srs_error_new(ERROR_ENCODER_NO_OUTPUT, "empty output url, ingest=%s", ingest->arg0().c_str());
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ using namespace std;
|
|||
#include <srs_kernel_utility.hpp>
|
||||
#include <srs_kernel_consts.hpp>
|
||||
#include <srs_protocol_utility.hpp>
|
||||
#include <srs_app_utility.hpp>
|
||||
|
||||
SrsNgExec::SrsNgExec()
|
||||
{
|
||||
|
@ -82,16 +83,18 @@ srs_error_t SrsNgExec::cycle()
|
|||
srs_error_t err = srs_success;
|
||||
|
||||
while (true) {
|
||||
if ((err = do_cycle()) != srs_success) {
|
||||
srs_warn("EXEC: Ignore error, %s", srs_error_desc(err).c_str());
|
||||
srs_freep(err);
|
||||
}
|
||||
|
||||
// We always check status first.
|
||||
// @see https://github.com/ossrs/srs/issues/1634#issuecomment-597571561
|
||||
if ((err = trd->pull()) != srs_success) {
|
||||
err = srs_error_wrap(err, "ng exec cycle");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if ((err = do_cycle()) != srs_success) {
|
||||
srs_warn("EXEC: Ignore error, %s", srs_error_desc(err).c_str());
|
||||
srs_freep(err);
|
||||
}
|
||||
|
||||
srs_usleep(SRS_RTMP_EXEC_CIMS);
|
||||
}
|
||||
|
||||
|
@ -219,6 +222,8 @@ string SrsNgExec::parse(SrsRequest* req, string tmpl)
|
|||
output = srs_string_replace(output, "[tcUrl]", req->tcUrl);
|
||||
output = srs_string_replace(output, "[swfUrl]", req->swfUrl);
|
||||
output = srs_string_replace(output, "[pageUrl]", req->pageUrl);
|
||||
|
||||
output = srs_path_build_timestamp(output);
|
||||
|
||||
if (output.find("[url]") != string::npos) {
|
||||
string url = srs_generate_rtmp_url(req->host, req->port, req->host, req->vhost, req->app, req->stream, req->param);
|
||||
|
|
|
@ -248,6 +248,10 @@ srs_error_t SrsProcess::start()
|
|||
|
||||
// parent.
|
||||
if (pid > 0) {
|
||||
// Wait for a while for process to really started.
|
||||
// @see https://github.com/ossrs/srs/issues/1634#issuecomment-597568840
|
||||
srs_usleep(10 * SRS_UTIME_MILLISECONDS);
|
||||
|
||||
is_started = true;
|
||||
srs_trace("fored process, pid=%d, bin=%s, stdout=%s, stderr=%s, argv=%s",
|
||||
pid, bin.c_str(), stdout_file.c_str(), stderr_file.c_str(), actual_cli.c_str());
|
||||
|
|
|
@ -381,7 +381,6 @@ srs_error_t SrsRtmpConn::service_cycle()
|
|||
}
|
||||
|
||||
while (true) {
|
||||
srs_error_t err = srs_success;
|
||||
if ((err = trd->pull()) != srs_success) {
|
||||
return srs_error_wrap(err, "rtmp: thread quit");
|
||||
}
|
||||
|
@ -704,14 +703,14 @@ srs_error_t SrsRtmpConn::do_playing(SrsSource* source, SrsConsumer* consumer, Sr
|
|||
srsu2msi(send_min_interval), srsu2msi(mw_sleep), mw_enabled, realtime, tcp_nodelay);
|
||||
|
||||
while (true) {
|
||||
// collect elapse for pithy print.
|
||||
pprint->elapse();
|
||||
|
||||
// when source is set to expired, disconnect it.
|
||||
if ((err = trd->pull()) != srs_success) {
|
||||
return srs_error_wrap(err, "rtmp: thread quit");
|
||||
}
|
||||
|
||||
|
||||
// collect elapse for pithy print.
|
||||
pprint->elapse();
|
||||
|
||||
// to use isolate thread to recv, can improve about 33% performance.
|
||||
// @see: https://github.com/ossrs/srs/issues/196
|
||||
// @see: https://github.com/ossrs/srs/issues/217
|
||||
|
@ -872,12 +871,12 @@ srs_error_t SrsRtmpConn::do_publishing(SrsSource* source, SrsPublishRecvThread*
|
|||
int64_t nb_msgs = 0;
|
||||
uint64_t nb_frames = 0;
|
||||
while (true) {
|
||||
pprint->elapse();
|
||||
|
||||
if ((err = trd->pull()) != srs_success) {
|
||||
return srs_error_wrap(err, "rtmp: thread quit");
|
||||
}
|
||||
|
||||
|
||||
pprint->elapse();
|
||||
|
||||
// cond wait for timeout.
|
||||
if (nb_msgs == 0) {
|
||||
// when not got msgs, wait for a larger timeout.
|
||||
|
|
|
@ -240,6 +240,12 @@ srs_error_t SrsRtspConn::serve()
|
|||
return err;
|
||||
}
|
||||
|
||||
std::string SrsRtspConn::remote_ip()
|
||||
{
|
||||
// TODO: FIXME: Implement it.
|
||||
return "";
|
||||
}
|
||||
|
||||
srs_error_t SrsRtspConn::do_cycle()
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
@ -684,6 +690,7 @@ SrsRtspCaster::SrsRtspCaster(SrsConfDirective* c)
|
|||
output = _srs_config->get_stream_caster_output(c);
|
||||
local_port_min = _srs_config->get_stream_caster_rtp_port_min(c);
|
||||
local_port_max = _srs_config->get_stream_caster_rtp_port_max(c);
|
||||
manager = new SrsCoroutineManager();
|
||||
}
|
||||
|
||||
SrsRtspCaster::~SrsRtspCaster()
|
||||
|
@ -691,10 +698,21 @@ SrsRtspCaster::~SrsRtspCaster()
|
|||
std::vector<SrsRtspConn*>::iterator it;
|
||||
for (it = clients.begin(); it != clients.end(); ++it) {
|
||||
SrsRtspConn* conn = *it;
|
||||
srs_freep(conn);
|
||||
manager->remove(conn);
|
||||
}
|
||||
clients.clear();
|
||||
used_ports.clear();
|
||||
|
||||
srs_freep(manager);
|
||||
}
|
||||
|
||||
srs_error_t SrsRtspCaster::initialize()
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
if ((err = manager->start()) != srs_success) {
|
||||
return srs_error_wrap(err, "start manager");
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtspCaster::alloc_port(int* pport)
|
||||
|
@ -747,6 +765,6 @@ void SrsRtspCaster::remove(SrsRtspConn* conn)
|
|||
}
|
||||
srs_info("rtsp: remove connection from caster.");
|
||||
|
||||
srs_freep(conn);
|
||||
manager->remove(conn);
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ public:
|
|||
};
|
||||
|
||||
// The rtsp connection serve the fd.
|
||||
class SrsRtspConn : public ISrsCoroutineHandler
|
||||
class SrsRtspConn : public ISrsCoroutineHandler, public ISrsConnection
|
||||
{
|
||||
private:
|
||||
std::string output_template;
|
||||
|
@ -143,6 +143,7 @@ public:
|
|||
virtual ~SrsRtspConn();
|
||||
public:
|
||||
virtual srs_error_t serve();
|
||||
virtual std::string remote_ip();
|
||||
private:
|
||||
virtual srs_error_t do_cycle();
|
||||
// internal methods
|
||||
|
@ -179,6 +180,7 @@ private:
|
|||
std::map<int, bool> used_ports;
|
||||
private:
|
||||
std::vector<SrsRtspConn*> clients;
|
||||
SrsCoroutineManager* manager;
|
||||
public:
|
||||
SrsRtspCaster(SrsConfDirective* c);
|
||||
virtual ~SrsRtspCaster();
|
||||
|
@ -188,6 +190,7 @@ public:
|
|||
virtual srs_error_t alloc_port(int* pport);
|
||||
// Free the alloced rtp port.
|
||||
virtual void free_port(int lpmin, int lpmax);
|
||||
virtual srs_error_t initialize();
|
||||
// Interface ISrsTcpHandler
|
||||
public:
|
||||
virtual srs_error_t on_tcp_client(srs_netfd_t stfd);
|
||||
|
|
|
@ -179,6 +179,9 @@ SrsRtspListener::SrsRtspListener(SrsServer* svr, SrsListenerType t, SrsConfDirec
|
|||
srs_assert(type == SrsListenerRtsp);
|
||||
if (type == SrsListenerRtsp) {
|
||||
caster = new SrsRtspCaster(c);
|
||||
|
||||
// TODO: FIXME: Must check error.
|
||||
caster->initialize();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -554,9 +557,11 @@ void SrsServer::gracefully_dispose()
|
|||
close_listeners(SrsListenerMpegTsOverUdp);
|
||||
close_listeners(SrsListenerRtsp);
|
||||
close_listeners(SrsListenerFlv);
|
||||
srs_trace("listeners closed");
|
||||
|
||||
// Fast stop to notify FFMPEG to quit, wait for a while then fast kill.
|
||||
ingester->stop();
|
||||
srs_trace("ingesters stopped");
|
||||
|
||||
// Wait for connections to quit.
|
||||
// While gracefully quiting, user can requires SRS to fast quit.
|
||||
|
@ -572,6 +577,7 @@ void SrsServer::gracefully_dispose()
|
|||
|
||||
// dispose the source for hls and dvr.
|
||||
_srs_sources->dispose();
|
||||
srs_trace("source disposed");
|
||||
|
||||
#ifdef SRS_AUTO_MEM_WATCH
|
||||
srs_memory_report();
|
||||
|
@ -884,6 +890,7 @@ srs_error_t SrsServer::cycle()
|
|||
void SrsServer::on_signal(int signo)
|
||||
{
|
||||
if (signo == SRS_SIGNAL_RELOAD) {
|
||||
srs_trace("reload config, signo=%d", signo);
|
||||
signal_reload = true;
|
||||
return;
|
||||
}
|
||||
|
@ -891,7 +898,7 @@ void SrsServer::on_signal(int signo)
|
|||
#ifndef SRS_AUTO_GPERF_MC
|
||||
if (signo == SRS_SIGNAL_REOPEN_LOG) {
|
||||
_srs_log->reopen();
|
||||
srs_warn("reopen log file");
|
||||
srs_warn("reopen log file, signo=%d", signo);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@ -899,7 +906,7 @@ void SrsServer::on_signal(int signo)
|
|||
#ifdef SRS_AUTO_GPERF_MC
|
||||
if (signo == SRS_SIGNAL_REOPEN_LOG) {
|
||||
signal_gmc_stop = true;
|
||||
srs_warn("for gmc, the SIGUSR1 used as SIGINT");
|
||||
srs_warn("for gmc, the SIGUSR1 used as SIGINT, signo=%d", signo);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@ -911,7 +918,7 @@ void SrsServer::on_signal(int signo)
|
|||
|
||||
if (signo == SIGINT) {
|
||||
#ifdef SRS_AUTO_GPERF_MC
|
||||
srs_trace("gmc is on, main cycle will terminate normally.");
|
||||
srs_trace("gmc is on, main cycle will terminate normally, signo=%d", signo);
|
||||
signal_gmc_stop = true;
|
||||
#else
|
||||
#ifdef SRS_AUTO_MEM_WATCH
|
||||
|
|
|
@ -50,6 +50,7 @@ class ISrsUdpHandler;
|
|||
class SrsUdpListener;
|
||||
class SrsTcpListener;
|
||||
class SrsAppCasterFlv;
|
||||
class SrsRtspCaster;
|
||||
class SrsCoroutineManager;
|
||||
|
||||
// The listener type for server to identify the connection,
|
||||
|
@ -107,7 +108,7 @@ class SrsRtspListener : virtual public SrsListener, virtual public ISrsTcpHandle
|
|||
{
|
||||
private:
|
||||
SrsTcpListener* listener;
|
||||
ISrsTcpHandler* caster;
|
||||
SrsRtspCaster* caster;
|
||||
public:
|
||||
SrsRtspListener(SrsServer* svr, SrsListenerType t, SrsConfDirective* c);
|
||||
virtual ~SrsRtspListener();
|
||||
|
|
|
@ -1506,6 +1506,7 @@ void SrsOriginHub::destroy_forwarders()
|
|||
SrsMetaCache::SrsMetaCache()
|
||||
{
|
||||
meta = video = audio = NULL;
|
||||
previous_video = previous_audio = NULL;
|
||||
vformat = new SrsRtmpFormat();
|
||||
aformat = new SrsRtmpFormat();
|
||||
}
|
||||
|
@ -1516,6 +1517,13 @@ SrsMetaCache::~SrsMetaCache()
|
|||
}
|
||||
|
||||
void SrsMetaCache::dispose()
|
||||
{
|
||||
clear();
|
||||
srs_freep(previous_video);
|
||||
srs_freep(previous_audio);
|
||||
}
|
||||
|
||||
void SrsMetaCache::clear()
|
||||
{
|
||||
srs_freep(meta);
|
||||
srs_freep(video);
|
||||
|
@ -1570,6 +1578,28 @@ srs_error_t SrsMetaCache::dumps(SrsConsumer* consumer, bool atc, SrsRtmpJitterAl
|
|||
return err;
|
||||
}
|
||||
|
||||
SrsSharedPtrMessage* SrsMetaCache::previous_vsh()
|
||||
{
|
||||
return previous_video;
|
||||
}
|
||||
|
||||
SrsSharedPtrMessage* SrsMetaCache::previous_ash()
|
||||
{
|
||||
return previous_audio;
|
||||
}
|
||||
|
||||
void SrsMetaCache::update_previous_vsh()
|
||||
{
|
||||
srs_freep(previous_video);
|
||||
previous_video = video? video->copy() : NULL;
|
||||
}
|
||||
|
||||
void SrsMetaCache::update_previous_ash()
|
||||
{
|
||||
srs_freep(previous_audio);
|
||||
previous_audio = audio? audio->copy() : NULL;
|
||||
}
|
||||
|
||||
srs_error_t SrsMetaCache::update_data(SrsMessageHeader* header, SrsOnMetaDataPacket* metadata, bool& updated)
|
||||
{
|
||||
updated = false;
|
||||
|
@ -1636,6 +1666,7 @@ srs_error_t SrsMetaCache::update_ash(SrsSharedPtrMessage* msg)
|
|||
{
|
||||
srs_freep(audio);
|
||||
audio = msg->copy();
|
||||
update_previous_ash();
|
||||
return aformat->on_audio(msg);
|
||||
}
|
||||
|
||||
|
@ -1643,6 +1674,7 @@ srs_error_t SrsMetaCache::update_vsh(SrsSharedPtrMessage* msg)
|
|||
{
|
||||
srs_freep(video);
|
||||
video = msg->copy();
|
||||
update_previous_vsh();
|
||||
return vformat->on_video(msg);
|
||||
}
|
||||
|
||||
|
@ -2138,9 +2170,9 @@ srs_error_t SrsSource::on_audio_imp(SrsSharedPtrMessage* msg)
|
|||
|
||||
// whether consumer should drop for the duplicated sequence header.
|
||||
bool drop_for_reduce = false;
|
||||
if (is_sequence_header && meta->ash() && _srs_config->get_reduce_sequence_header(req->vhost)) {
|
||||
if (meta->ash()->size == msg->size) {
|
||||
drop_for_reduce = srs_bytes_equals(meta->ash()->payload, msg->payload, msg->size);
|
||||
if (is_sequence_header && meta->previous_ash() && _srs_config->get_reduce_sequence_header(req->vhost)) {
|
||||
if (meta->previous_ash()->size == msg->size) {
|
||||
drop_for_reduce = srs_bytes_equals(meta->previous_ash()->payload, msg->payload, msg->size);
|
||||
srs_warn("drop for reduce sh audio, size=%d", msg->size);
|
||||
}
|
||||
}
|
||||
|
@ -2257,9 +2289,9 @@ srs_error_t SrsSource::on_video_imp(SrsSharedPtrMessage* msg)
|
|||
|
||||
// whether consumer should drop for the duplicated sequence header.
|
||||
bool drop_for_reduce = false;
|
||||
if (is_sequence_header && meta->vsh() && _srs_config->get_reduce_sequence_header(req->vhost)) {
|
||||
if (meta->vsh()->size == msg->size) {
|
||||
drop_for_reduce = srs_bytes_equals(meta->vsh()->payload, msg->payload, msg->size);
|
||||
if (is_sequence_header && meta->previous_vsh() && _srs_config->get_reduce_sequence_header(req->vhost)) {
|
||||
if (meta->previous_vsh()->size == msg->size) {
|
||||
drop_for_reduce = srs_bytes_equals(meta->previous_vsh()->payload, msg->payload, msg->size);
|
||||
srs_warn("drop for reduce sh video, size=%d", msg->size);
|
||||
}
|
||||
}
|
||||
|
@ -2415,6 +2447,10 @@ srs_error_t SrsSource::on_publish()
|
|||
|
||||
// reset the mix queue.
|
||||
mix_queue->clear();
|
||||
|
||||
// Reset the metadata cache, to make VLC happy when disable/enable stream.
|
||||
// @see https://github.com/ossrs/srs/issues/1630#issuecomment-597979448
|
||||
meta->clear();
|
||||
|
||||
// detect the monotonically again.
|
||||
is_monotonically_increase = true;
|
||||
|
@ -2450,7 +2486,12 @@ void SrsSource::on_unpublish()
|
|||
// donot clear the sequence header, for it maybe not changed,
|
||||
// when drop dup sequence header, drop the metadata also.
|
||||
gop_cache->clear();
|
||||
|
||||
|
||||
// Reset the metadata cache, to make VLC happy when disable/enable stream.
|
||||
// @see https://github.com/ossrs/srs/issues/1630#issuecomment-597979448
|
||||
meta->update_previous_vsh();
|
||||
meta->update_previous_ash();
|
||||
|
||||
srs_trace("cleanup when unpublish");
|
||||
|
||||
_can_publish = true;
|
||||
|
|
|
@ -407,8 +407,10 @@ private:
|
|||
SrsSharedPtrMessage* meta;
|
||||
// The cached video sequence header, for example, sps/pps for h.264.
|
||||
SrsSharedPtrMessage* video;
|
||||
SrsSharedPtrMessage* previous_video;
|
||||
// The cached audio sequence header, for example, asc for aac.
|
||||
SrsSharedPtrMessage* audio;
|
||||
SrsSharedPtrMessage* previous_audio;
|
||||
// The format for sequence header.
|
||||
SrsRtmpFormat* vformat;
|
||||
SrsRtmpFormat* aformat;
|
||||
|
@ -418,6 +420,8 @@ public:
|
|||
public:
|
||||
// Dispose the metadata cache.
|
||||
virtual void dispose();
|
||||
// For each publishing, clear the metadata cache.
|
||||
virtual void clear();
|
||||
public:
|
||||
// Get the cached metadata.
|
||||
virtual SrsSharedPtrMessage* data();
|
||||
|
@ -431,6 +435,13 @@ public:
|
|||
// @param dm Whether dumps the metadata.
|
||||
// @param ds Whether dumps the sequence header.
|
||||
virtual srs_error_t dumps(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm ag, bool dm, bool ds);
|
||||
public:
|
||||
// Previous exists sequence header.
|
||||
virtual SrsSharedPtrMessage* previous_vsh();
|
||||
virtual SrsSharedPtrMessage* previous_ash();
|
||||
// Update previous sequence header, drop old one, set to new sequence header.
|
||||
virtual void update_previous_vsh();
|
||||
virtual void update_previous_ash();
|
||||
public:
|
||||
// Update the cached metadata by packet.
|
||||
virtual srs_error_t update_data(SrsMessageHeader* header, SrsOnMetaDataPacket* metadata, bool& updated);
|
||||
|
|
|
@ -24,6 +24,6 @@
|
|||
#ifndef SRS_CORE_VERSION3_HPP
|
||||
#define SRS_CORE_VERSION3_HPP
|
||||
|
||||
#define SRS_VERSION3_REVISION 123
|
||||
#define SRS_VERSION3_REVISION 128
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,6 +24,6 @@
|
|||
#ifndef SRS_CORE_VERSION4_HPP
|
||||
#define SRS_CORE_VERSION4_HPP
|
||||
|
||||
#define SRS_VERSION4_REVISION 10
|
||||
#define SRS_VERSION4_REVISION 12
|
||||
|
||||
#endif
|
||||
|
|
|
@ -48,6 +48,7 @@ using namespace std;
|
|||
#include <srs_core_performance.hpp>
|
||||
#include <srs_app_utility.hpp>
|
||||
#include <srs_core_autofree.hpp>
|
||||
#include <srs_kernel_file.hpp>
|
||||
#include <srs_app_hybrid.hpp>
|
||||
|
||||
#ifdef SRS_AUTO_SRT
|
||||
|
@ -354,12 +355,56 @@ string srs_getenv(const char* name)
|
|||
return "";
|
||||
}
|
||||
|
||||
// Detect docker by https://stackoverflow.com/a/41559867
|
||||
srs_error_t srs_detect_docker(bool* is_docker)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
*is_docker = false;
|
||||
|
||||
SrsFileReader fr;
|
||||
if ((err = fr.open("/proc/1/cgroup")) != srs_success) {
|
||||
return err;
|
||||
}
|
||||
|
||||
ssize_t nn;
|
||||
char buf[1024];
|
||||
if ((err = fr.read(buf, sizeof(buf), &nn)) != srs_success) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (nn <= 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
string s(buf, nn);
|
||||
if (srs_string_contains(s, "/docker")) {
|
||||
*is_docker = true;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t run_directly_or_daemon()
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// Load daemon from config, disable it for docker.
|
||||
// @see https://github.com/ossrs/srs/issues/1594
|
||||
bool in_daemon = _srs_config->get_daemon();
|
||||
if (in_daemon && _srs_config->disable_daemon_for_docker()) {
|
||||
bool is_docker = false;
|
||||
err = srs_detect_docker(&is_docker);
|
||||
srs_error_reset(err); // Ignore any error while detecting docker.
|
||||
|
||||
if (is_docker) {
|
||||
srs_warn("disable daemon for docker");
|
||||
in_daemon = false;
|
||||
}
|
||||
}
|
||||
|
||||
// If not daemon, directly run master.
|
||||
if (!_srs_config->get_daemon()) {
|
||||
if (!in_daemon) {
|
||||
if ((err = run_hybrid_server()) != srs_success) {
|
||||
return srs_error_wrap(err, "run master");
|
||||
}
|
||||
|
|
|
@ -460,6 +460,7 @@ srs_error_t rtmp_client::on_ts_video(std::shared_ptr<SrsBuffer> avs_ptr, uint64_
|
|||
continue;
|
||||
}
|
||||
|
||||
// TODO: FIXME: Should cache this config, it's better not to get it for each video frame.
|
||||
if (_srs_config->get_srt_sei_filter()) {
|
||||
if (nal_unit_type == SrsAvcNaluTypeSEI) {
|
||||
continue;
|
||||
|
|
Loading…
Reference in a new issue