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

Squash: Merge SRS 4.0

This commit is contained in:
winlin 2021-10-10 12:05:26 +08:00
parent 6c597facfb
commit a81aa2edc5
65 changed files with 276 additions and 5990 deletions

File diff suppressed because it is too large Load diff

View file

@ -100,7 +100,6 @@ extern bool srs_config_ingest_is_stream(std::string type);
extern bool srs_config_dvr_is_plan_segment(std::string plan);
extern bool srs_config_dvr_is_plan_session(std::string plan);
extern bool srs_stream_caster_is_udp(std::string caster);
extern bool srs_stream_caster_is_rtsp(std::string caster);
extern bool srs_stream_caster_is_flv(std::string caster);
// Whether the dvr_apply active the stream specified by req.
extern bool srs_config_apply_filter(SrsConfDirective* dvr_apply, SrsRequest* req);
@ -333,44 +332,8 @@ public:
private:
virtual srs_error_t do_persistence(SrsFileWriter* fw);
public:
// Dumps the global sections to json.
virtual srs_error_t global_to_json(SrsJsonObject* obj);
// Dumps the minimal sections to json.
virtual srs_error_t minimal_to_json(SrsJsonObject* obj);
// Dumps the vhost section to json.
virtual srs_error_t vhost_to_json(SrsConfDirective* vhost, SrsJsonObject* obj);
// Dumps the http_api sections to json for raw api info.
virtual srs_error_t raw_to_json(SrsJsonObject* obj);
// RAW set the global listen.
virtual srs_error_t raw_set_listen(const std::vector<std::string>& eps, bool& applied);
// RAW set the global pid.
virtual srs_error_t raw_set_pid(std::string pid, bool& applied);
// RAW set the global chunk size.
virtual srs_error_t raw_set_chunk_size(std::string chunk_size, bool& applied);
// RAW set the global ffmpeg log dir.
virtual srs_error_t raw_set_ff_log_dir(std::string ff_log_dir, bool& applied);
// RAW set the global log tank.
virtual srs_error_t raw_set_srs_log_tank(std::string srs_log_tank, bool& applied);
// RAW set the global log level.
virtual srs_error_t raw_set_srs_log_level(std::string srs_log_level, bool& applied);
// RAW set the global log file path for file tank.
virtual srs_error_t raw_set_srs_log_file(std::string srs_log_file, bool& applied);
// RAW set the global max connections of srs.
virtual srs_error_t raw_set_max_connections(std::string max_connections, bool& applied);
// RAW set the global whether use utc time.
virtual srs_error_t raw_set_utc_time(std::string utc_time, bool& applied);
// RAW set the global pithy print interval in ms.
virtual srs_error_t raw_set_pithy_print_ms(std::string pithy_print_ms, bool& applied);
// RAW create the new vhost.
virtual srs_error_t raw_create_vhost(std::string vhost, bool& applied);
// RAW update the disabled vhost name.
virtual srs_error_t raw_update_vhost(std::string vhost, std::string name, bool& applied);
// RAW delete the disabled vhost.
virtual srs_error_t raw_delete_vhost(std::string vhost, bool& applied);
// RAW disable the enabled vhost.
virtual srs_error_t raw_disable_vhost(std::string vhost, bool& applied);
// RAW enable the disabled vhost.
virtual srs_error_t raw_enable_vhost(std::string vhost, bool& applied);
private:
virtual srs_error_t do_reload_listen();
virtual srs_error_t do_reload_pid();
@ -750,7 +713,6 @@ public:
// all clients connected to edge must be tranverse to origin to verify.
virtual bool get_vhost_edge_token_traverse(std::string vhost);
// Get the transformed vhost for edge,
// @see https://github.com/ossrs/srs/issues/372
virtual std::string get_vhost_edge_transform_vhost(std::string vhost);
// Whether enable the origin cluster.
// @see https://github.com/ossrs/srs/wiki/v3_EN_OriginCluster
@ -925,7 +887,6 @@ public:
// Get the hls hls_on_error config.
// The ignore will ignore error and disable hls.
// The disconnect will disconnect publish connection.
// @see https://github.com/ossrs/srs/issues/264
virtual std::string get_hls_on_error(std::string vhost);
// Get the HLS default audio codec.
virtual std::string get_hls_acodec(std::string vhost);

View file

@ -71,7 +71,6 @@ srs_error_t SrsEdgeRtmpUpstream::connect(SrsRequest* r, SrsLbRoundRobin* lb)
if (true) {
SrsConfDirective* conf = _srs_config->get_vhost_edge_origin(req->vhost);
// @see https://github.com/ossrs/srs/issues/79
// when origin is error, for instance, server is shutdown,
// then user remove the vhost then reload, the conf is empty.
if (!conf) {
@ -98,7 +97,6 @@ srs_error_t SrsEdgeRtmpUpstream::connect(SrsRequest* r, SrsLbRoundRobin* lb)
selected_port = port;
// support vhost tranform for edge,
// @see https://github.com/ossrs/srs/issues/372
std::string vhost = _srs_config->get_vhost_edge_transform_vhost(req->vhost);
vhost = srs_string_replace(vhost, "[vhost]", req->vhost);
@ -724,7 +722,6 @@ srs_error_t SrsEdgeForwarder::start()
srs_parse_hostport(server, server, port);
// support vhost tranform for edge,
// @see https://github.com/ossrs/srs/issues/372
std::string vhost = _srs_config->get_vhost_edge_transform_vhost(req->vhost);
vhost = srs_string_replace(vhost, "[vhost]", req->vhost);
@ -1005,7 +1002,6 @@ srs_error_t SrsPublishEdge::on_client_publish()
return srs_error_new(ERROR_RTMP_EDGE_PUBLISH_STATE, "invalid state");
}
// @see https://github.com/ossrs/srs/issues/180
// to avoid multiple publish the same stream on the same edge,
// directly enter the publish stage.
if (true) {
@ -1017,7 +1013,6 @@ srs_error_t SrsPublishEdge::on_client_publish()
// start to forward stream to origin.
err = forwarder->start();
// @see https://github.com/ossrs/srs/issues/180
// when failed, revert to init
if (err != srs_success) {
SrsEdgeState pstate = state;

View file

@ -40,7 +40,6 @@ private:
SrsRtmpJitter* jitter;
SrsMessageQueue* queue;
// Cache the sequence header for retry when slave is failed.
// @see https://github.com/ossrs/srs/issues/150
SrsSharedPtrMessage* sh_audio;
SrsSharedPtrMessage* sh_video;
public:

View file

@ -153,7 +153,6 @@ private:
// The current writing segment.
SrsHlsSegment* current;
// The ts context, to keep cc continous between ts.
// @see https://github.com/ossrs/srs/issues/375
SrsTsContext* context;
public:
SrsHlsMuxer();
@ -187,7 +186,6 @@ public:
virtual bool wait_keyframe();
// Whether segment absolutely overflow, for pure audio to reap segment,
// that is whether the current segment duration>=2*(the segment in config)
// @see https://github.com/ossrs/srs/issues/151#issuecomment-71155184
virtual bool is_segment_absolutely_overflow();
public:
// Whether current hls muxer is pure audio mode.

View file

@ -902,7 +902,7 @@ srs_error_t SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage*
//////////////////////////////////////////////////////////////////////////
// the rpc is required.
// the allowd rpc method check.
if (rpc.empty() || (rpc != "reload" && rpc != "query" && rpc != "raw" && rpc != "update")) {
if (rpc.empty() || rpc != "reload") {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW);
}
@ -916,312 +916,6 @@ srs_error_t SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage*
return srs_api_response_code(w, r, ERROR_SUCCESS);
}
// for rpc=query, to get the configs of server.
// @param scope the scope to query for config, it can be:
// global, the configs belongs to the root, donot includes any sub directives.
// minimal, the minimal summary of server, for preview stream to got the port serving.
// vhost, the configs for specified vhost by @param vhost.
// @param vhost the vhost name for @param scope is vhost to query config.
// for the default vhost, must be __defaultVhost__
if (rpc == "query") {
if (!allow_query) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_DISABLED);
}
std::string scope = r->query_get("scope");
std::string vhost = r->query_get("vhost");
if (scope.empty() || (scope != "global" && scope != "vhost" && scope != "minimal")) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_NOT_ALLOWED);
}
if (scope == "vhost") {
// query vhost scope.
if (vhost.empty()) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_PARAMS);
}
SrsConfDirective* root = _srs_config->get_root();
SrsConfDirective* conf = root->get("vhost", vhost);
if (!conf) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_PARAMS);
}
SrsJsonObject* data = SrsJsonAny::object();
obj->set("vhost", data);
if ((err = _srs_config->vhost_to_json(conf, data)) != srs_success) {
int code = srs_error_code(err);
srs_error_reset(err);
return srs_api_response_code(w, r, code);
}
} else if (scope == "minimal") {
SrsJsonObject* data = SrsJsonAny::object();
obj->set("minimal", data);
// query minimal scope.
if ((err = _srs_config->minimal_to_json(data)) != srs_success) {
int code = srs_error_code(err);
srs_error_reset(err);
return srs_api_response_code(w, r, code);
}
} else {
SrsJsonObject* data = SrsJsonAny::object();
obj->set("global", data);
// query global scope.
if ((err = _srs_config->global_to_json(data)) != srs_success) {
int code = srs_error_code(err);
srs_error_reset(err);
return srs_api_response_code(w, r, code);
}
}
return srs_api_response(w, r, obj->dumps());
}
// for rpc=update, to update the configs of server.
// @scope the scope to update for config.
// @value the updated value for scope.
// @param the extra param for scope.
// @data the extra data for scope.
// possible updates:
// @scope @value value-description
// listen 1935,1936 the port list.
// pid ./objs/srs.pid the pid file of srs.
// chunk_size 60000 the global RTMP chunk_size.
// ff_log_dir ./objs the dir for ffmpeg log.
// srs_log_tank file the tank to log, file or console.
// srs_log_level trace the level of log, verbose, info, trace, warn, error.
// srs_log_file ./objs/srs.log the log file when tank is file.
// max_connections 1000 the max connections of srs.
// utc_time false whether enable utc time.
// pithy_print_ms 10000 the pithy print interval in ms.
// vhost specified updates:
// @scope @value @param @data description
// vhost ossrs.net create - create vhost ossrs.net
// vhost ossrs.net update new.ossrs.net the new name to update vhost
// dvr specified updates:
// @scope @value @param @data description
// dvr ossrs.net enable live/livestream enable the dvr of stream
// dvr ossrs.net disable live/livestream disable the dvr of stream
if (rpc == "update") {
if (!allow_update) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_DISABLED);
}
std::string scope = r->query_get("scope");
std::string value = r->query_get("value");
if (scope.empty()) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_NOT_ALLOWED);
}
if (scope != "listen" && scope != "pid" && scope != "chunk_size"
&& scope != "ff_log_dir" && scope != "srs_log_tank" && scope != "srs_log_level"
&& scope != "srs_log_file" && scope != "max_connections" && scope != "utc_time"
&& scope != "pithy_print_ms" && scope != "vhost" && scope != "dvr"
) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_NOT_ALLOWED);
}
bool applied = false;
string extra = "";
if (scope == "listen") {
vector<string> eps = srs_string_split(value, ",");
bool invalid = eps.empty();
for (int i = 0; i < (int)eps.size(); i++) {
string ep = eps.at(i);
int port = ::atoi(ep.c_str());
if (port <= 2 || port >= 65535) {
invalid = true;
break;
}
}
if (invalid) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_PARAMS);
}
if ((err = _srs_config->raw_set_listen(eps, applied)) != srs_success) {
int code = srs_error_code(err);
srs_error_reset(err);
return srs_api_response_code(w, r, code);
}
} else if (scope == "pid") {
if (value.empty() || !srs_string_starts_with(value, "./", "/tmp/", "/var/") || !srs_string_ends_with(value, ".pid")) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_PARAMS);
}
if ((err = _srs_config->raw_set_pid(value, applied)) != srs_success) {
int code = srs_error_code(err);
srs_error_reset(err);
return srs_api_response_code(w, r, code);
}
} else if (scope == "chunk_size") {
int csv = ::atoi(value.c_str());
if (csv < 128 || csv > 65535 || !srs_is_digit_number(value)) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_PARAMS);
}
if ((err = _srs_config->raw_set_chunk_size(value, applied)) != srs_success) {
int code = srs_error_code(err);
srs_error_reset(err);
return srs_api_response_code(w, r, code);
}
} else if (scope == "ff_log_dir") {
if (value.empty() || (value != "/dev/null" && !srs_string_starts_with(value, "./", "/tmp/", "/var/"))) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_PARAMS);
}
if ((err = _srs_config->raw_set_ff_log_dir(value, applied)) != srs_success) {
int code = srs_error_code(err);
srs_error_reset(err);
return srs_api_response_code(w, r, code);
}
} else if (scope == "srs_log_tank") {
if (value.empty() || (value != "file" && value != "console")) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_PARAMS);
}
if ((err = _srs_config->raw_set_srs_log_tank(value, applied)) != srs_success) {
int code = srs_error_code(err);
srs_error_reset(err);
return srs_api_response_code(w, r, code);
}
} else if (scope == "srs_log_level") {
if (value != "verbose" && value != "info" && value != "trace" && value != "warn" && value != "error") {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_PARAMS);
}
if ((err = _srs_config->raw_set_srs_log_level(value, applied)) != srs_success) {
int code = srs_error_code(err);
srs_error_reset(err);
return srs_api_response_code(w, r, code);
}
} else if (scope == "srs_log_file") {
if (value.empty() || !srs_string_starts_with(value, "./", "/tmp/", "/var/") || !srs_string_ends_with(value, ".log")) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_PARAMS);
}
if ((err = _srs_config->raw_set_srs_log_file(value, applied)) != srs_success) {
int code = srs_error_code(err);
srs_error_reset(err);
return srs_api_response_code(w, r, code);
}
} else if (scope == "max_connections") {
int mcv = ::atoi(value.c_str());
if (mcv < 10 || mcv > 65535 || !srs_is_digit_number(value)) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_PARAMS);
}
if ((err = _srs_config->raw_set_max_connections(value, applied)) != srs_success) {
int code = srs_error_code(err);
srs_error_reset(err);
return srs_api_response_code(w, r, code);
}
} else if (scope == "utc_time") {
if (!srs_is_boolean(value)) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_PARAMS);
}
if ((err = _srs_config->raw_set_utc_time(srs_config_bool2switch(value), applied)) != srs_success) {
return srs_api_response_code(w, r, srs_error_wrap(err, "raw api update utc_time=%s", value.c_str()));
}
} else if (scope == "pithy_print_ms") {
int ppmv = ::atoi(value.c_str());
if (ppmv < 100 || ppmv > 300000 || !srs_is_digit_number(value)) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_PARAMS);
}
if ((err = _srs_config->raw_set_pithy_print_ms(value, applied)) != srs_success) {
int code = srs_error_code(err);
srs_error_reset(err);
return srs_api_response_code(w, r, code);
}
} else if (scope == "vhost") {
std::string param = r->query_get("param");
std::string data = r->query_get("data");
if (param != "create" && param != "update" && param != "delete" && param != "disable" && param != "enable") {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_NOT_ALLOWED);
}
extra += " " + param;
if (param == "create") {
// when create, the vhost must not exists.
if (param.empty() || _srs_config->get_vhost(value, false)) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_PARAMS);
}
if ((err = _srs_config->raw_create_vhost(value, applied)) != srs_success) {
int code = srs_error_code(err);
srs_error_reset(err);
return srs_api_response_code(w, r, code);
}
} else if (param == "update") {
extra += " to " + data;
// when update, the vhost must exists and disabled.
SrsConfDirective* vhost = _srs_config->get_vhost(value, false);
if (data.empty() || data == value || param.empty() || !vhost || _srs_config->get_vhost_enabled(vhost)) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_PARAMS);
}
if ((err = _srs_config->raw_update_vhost(value, data, applied)) != srs_success) {
int code = srs_error_code(err);
srs_error_reset(err);
return srs_api_response_code(w, r, code);
}
} else if (param == "delete") {
// when delete, the vhost must exists and disabled.
SrsConfDirective* vhost = _srs_config->get_vhost(value, false);
if (param.empty() || !vhost || _srs_config->get_vhost_enabled(vhost)) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_PARAMS);
}
if ((err = _srs_config->raw_delete_vhost(value, applied)) != srs_success) {
int code = srs_error_code(err);
srs_error_reset(err);
return srs_api_response_code(w, r, code);
}
} else if (param == "disable") {
// when disable, the vhost must exists and enabled.
SrsConfDirective* vhost = _srs_config->get_vhost(value, false);
if (param.empty() || !vhost || !_srs_config->get_vhost_enabled(vhost)) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_PARAMS);
}
if ((err = _srs_config->raw_disable_vhost(value, applied)) != srs_success) {
int code = srs_error_code(err);
srs_error_reset(err);
return srs_api_response_code(w, r, code);
}
} else if (param == "enable") {
// when enable, the vhost must exists and disabled.
SrsConfDirective* vhost = _srs_config->get_vhost(value, false);
if (param.empty() || !vhost || _srs_config->get_vhost_enabled(vhost)) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW_PARAMS);
}
if ((err = _srs_config->raw_enable_vhost(value, applied)) != srs_success) {
int code = srs_error_code(err);
srs_error_reset(err);
return srs_api_response_code(w, r, code);
}
} else {
// TODO: support other param.
}
} else {
// TODO: support other scope.
}
// whether the config applied.
if (applied) {
server->on_signal(SRS_SIGNAL_PERSISTENCE_CONFIG);
srs_trace("raw api update %s=%s%s ok.", scope.c_str(), value.c_str(), extra.c_str());
} else {
srs_warn("raw api update not applied %s=%s%s.", scope.c_str(), value.c_str(), extra.c_str());
}
return srs_api_response(w, r, obj->dumps());
}
return err;
}

View file

@ -509,7 +509,6 @@ srs_error_t SrsHttpHooks::do_post(SrsHttpClient* hc, std::string url, std::strin
}
// ensure the http status is ok.
// https://github.com/ossrs/srs/issues/158
if (code != SRS_CONSTS_HTTP_OK && code != SRS_CONSTS_HTTP_Created) {
return srs_error_new(ERROR_HTTP_STATUS_INVALID, "http: status %d", code);
}

View file

@ -928,7 +928,6 @@ srs_error_t SrsHttpStreamServer::http_mount(SrsLiveSource* s, SrsRequest* r)
// mount the http flv stream.
// we must register the handler, then start the thread,
// for the thread will cause thread switch context.
// @see https://github.com/ossrs/srs/issues/404
if ((err = mux.handle(mount, entry->stream)) != srs_success) {
return srs_error_wrap(err, "http: mount flv stream for vhost=%s failed", sid.c_str());
}

View file

@ -449,7 +449,6 @@ srs_error_t SrsMpegtsOverUdp::write_h264_ipb_frame(char* frame, int frame_size,
srs_error_t err = srs_success;
// when sps or pps not sent, ignore the packet.
// @see https://github.com/ossrs/srs/issues/203
if (!h264_sps_pps_sent) {
return srs_error_new(ERROR_H264_DROP_BEFORE_SPS_PPS, "drop sps/pps");
}

View file

@ -93,8 +93,6 @@ srs_error_t SrsRecvThread::cycle()
// the multiple messages writev improve performance large,
// but the timeout recv will cause 33% sys call performance,
// to use isolate thread to recv, can improve about 33% performance.
// @see https://github.com/ossrs/srs/issues/194
// @see: https://github.com/ossrs/srs/issues/217
rtmp->set_recv_timeout(SRS_UTIME_NO_TIMEOUT);
pumper->on_start();
@ -279,7 +277,6 @@ SrsPublishRecvThread::SrsPublishRecvThread(SrsRtmpServer* rtmp_sdk, SrsRequest*
mr_fd = mr_sock_fd;
// the mr settings,
// @see https://github.com/ossrs/srs/issues/241
mr = _srs_config->get_mr_enabled(req->vhost);
mr_sleep = _srs_config->get_mr_sleep(req->vhost);
@ -405,7 +402,6 @@ void SrsPublishRecvThread::interrupt(srs_error_t err)
recv_error = srs_error_copy(err);
// when recv thread error, signal the conn thread to process it.
// @see https://github.com/ossrs/srs/issues/244
srs_cond_signal(error);
}
@ -420,7 +416,6 @@ void SrsPublishRecvThread::on_start()
set_socket_buffer(mr_sleep);
// disable the merge read
// @see https://github.com/ossrs/srs/issues/241
rtmp->set_merge_read(true, this);
}
#endif
@ -432,13 +427,11 @@ void SrsPublishRecvThread::on_stop()
// for we donot set to false yet.
// when thread stop, signal the conn thread which wait.
// @see https://github.com/ossrs/srs/issues/244
srs_cond_signal(error);
#ifdef SRS_PERF_MERGED_READ
if (mr) {
// disable the merge read
// @see https://github.com/ossrs/srs/issues/241
rtmp->set_merge_read(false, NULL);
}
#endif
@ -459,7 +452,6 @@ void SrsPublishRecvThread::on_read(ssize_t nread)
* to improve read performance, merge some packets then read,
* when it on and read small bytes, we sleep to wait more data.,
* that is, we merge some data to read together.
* @see https://github.com/ossrs/srs/issues/241
*/
if (nread < SRS_MR_SMALL_BYTES) {
srs_usleep(mr_sleep);
@ -476,7 +468,6 @@ srs_error_t SrsPublishRecvThread::on_reload_vhost_publish(string vhost)
}
// the mr settings,
// @see https://github.com/ossrs/srs/issues/241
bool mr_enabled = _srs_config->get_mr_enabled(req->vhost);
srs_utime_t sleep_v = _srs_config->get_mr_sleep(req->vhost);
@ -489,13 +480,11 @@ srs_error_t SrsPublishRecvThread::on_reload_vhost_publish(string vhost)
// mr enabled=>disabled
if (mr && !mr_enabled) {
// disable the merge read
// @see https://github.com/ossrs/srs/issues/241
rtmp->set_merge_read(false, NULL);
}
// mr disabled=>enabled
if (!mr && mr_enabled) {
// enable the merge read
// @see https://github.com/ossrs/srs/issues/241
rtmp->set_merge_read(true, this);
}
#endif

View file

@ -75,7 +75,6 @@ private:
// when source id changed, notice all consumers
bool should_update_source_id;
// The cond wait for mw.
// @see https://github.com/ossrs/srs/issues/251
srs_cond_t mw_wait;
bool mw_waiting;
int mw_min_msgs;

View file

@ -429,7 +429,6 @@ srs_error_t SrsRtmpConn::service_cycle()
// logical accept and retry stream service.
if (srs_error_code(err) == ERROR_CONTROL_RTMP_CLOSE) {
// TODO: FIXME: use ping message to anti-death of socket.
// @see: https://github.com/ossrs/srs/issues/39
// set timeout to a larger value, for user paused.
rtmp->set_recv_timeout(SRS_PAUSED_RECV_TIMEOUT);
rtmp->set_send_timeout(SRS_PAUSED_SEND_TIMEOUT);
@ -670,7 +669,6 @@ srs_error_t SrsRtmpConn::playing(SrsLiveSource* source)
}
// Use receiving thread to receive packets from peer.
// @see: https://github.com/ossrs/srs/issues/217
SrsQueueRecvThread trd(consumer, rtmp, SRS_PERF_MW_SLEEP, _srs_context->get_id());
if ((err = trd.start()) != srs_success) {
@ -731,8 +729,6 @@ srs_error_t SrsRtmpConn::do_playing(SrsLiveSource* source, SrsLiveConsumer* cons
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
while (!rtrd->empty()) {
SrsCommonMessage* msg = rtrd->pump();
if ((err = process_play_control_msg(consumer, msg)) != srs_success) {
@ -1114,7 +1110,6 @@ srs_error_t SrsRtmpConn::process_play_control_msg(SrsLiveConsumer* consumer, Srs
SrsAutoFree(SrsPacket, pkt);
// for jwplayer/flowplayer, which send close as pause message.
// @see https://github.com/ossrs/srs/issues/6
SrsCloseStreamPacket* close = dynamic_cast<SrsCloseStreamPacket*>(pkt);
if (close) {
return srs_error_new(ERROR_CONTROL_RTMP_CLOSE, "rtmp: close stream");
@ -1122,7 +1117,6 @@ srs_error_t SrsRtmpConn::process_play_control_msg(SrsLiveConsumer* consumer, Srs
// call msg,
// support response null first,
// @see https://github.com/ossrs/srs/issues/106
// TODO: FIXME: response in right way, or forward in edge mode.
SrsCallPacket* call = dynamic_cast<SrsCallPacket*>(pkt);
if (call) {

View file

@ -82,7 +82,6 @@ private:
ISrsWakable* wakable;
// The elapsed duration in srs_utime_t
// For live play duration, for instance, rtmpdump to record.
// @see https://github.com/ossrs/srs/issues/47
srs_utime_t duration;
// The MR(merged-write) sleep time in srs_utime_t.
srs_utime_t mw_sleep;

View file

@ -1,785 +0,0 @@
//
// Copyright (c) 2013-2021 The SRS Authors
//
// SPDX-License-Identifier: MIT
//
#include <srs_app_rtsp.hpp>
#include <algorithm>
using namespace std;
#include <srs_app_config.hpp>
#include <srs_kernel_error.hpp>
#include <srs_rtsp_stack.hpp>
#include <srs_app_st.hpp>
#include <srs_kernel_log.hpp>
#include <srs_app_utility.hpp>
#include <srs_core_autofree.hpp>
#include <srs_kernel_buffer.hpp>
#include <srs_kernel_stream.hpp>
#include <srs_rtmp_stack.hpp>
#include <srs_protocol_amf0.hpp>
#include <srs_protocol_utility.hpp>
#include <srs_kernel_utility.hpp>
#include <srs_raw_avc.hpp>
#include <srs_kernel_codec.hpp>
#include <srs_app_pithy_print.hpp>
#include <srs_app_rtmp_conn.hpp>
#include <srs_protocol_utility.hpp>
#include <srs_protocol_format.hpp>
SrsRtpConn::SrsRtpConn(SrsRtspConn* r, int p, int sid)
{
rtsp = r;
_port = p;
stream_id = sid;
// TODO: support listen at <[ip:]port>
listener = new SrsUdpListener(this, srs_any_address_for_listener(), p);
cache = new SrsRtspPacket();
pprint = SrsPithyPrint::create_caster();
}
SrsRtpConn::~SrsRtpConn()
{
srs_freep(listener);
srs_freep(cache);
srs_freep(pprint);
}
int SrsRtpConn::port()
{
return _port;
}
srs_error_t SrsRtpConn::listen()
{
return listener->listen();
}
srs_error_t SrsRtpConn::on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf)
{
srs_error_t err = srs_success;
pprint->elapse();
if (true) {
SrsBuffer stream(buf, nb_buf);
SrsRtspPacket pkt;
if ((err = pkt.decode(&stream)) != srs_success) {
return srs_error_wrap(err, "decode");
}
if (pkt.chunked) {
if (!cache) {
cache = new SrsRtspPacket();
}
cache->copy(&pkt);
cache->payload->append(pkt.payload->bytes(), pkt.payload->length());
if (pprint->can_print()) {
srs_trace("<- " SRS_CONSTS_LOG_STREAM_CASTER " rtsp: rtp chunked %dB, age=%d, vt=%d/%u, sts=%u/%#x/%#x, paylod=%dB",
nb_buf, pprint->age(), cache->version, cache->payload_type, cache->sequence_number, cache->timestamp, cache->ssrc,
cache->payload->length()
);
}
if (!cache->completed){
return err;
}
} else {
srs_freep(cache);
cache = new SrsRtspPacket();
cache->reap(&pkt);
}
}
if (pprint->can_print()) {
srs_trace("<- " SRS_CONSTS_LOG_STREAM_CASTER " rtsp: rtp #%d %dB, age=%d, vt=%d/%u, sts=%u/%u/%#x, paylod=%dB, chunked=%d",
stream_id, nb_buf, pprint->age(), cache->version, cache->payload_type, cache->sequence_number, cache->timestamp, cache->ssrc,
cache->payload->length(), cache->chunked
);
}
// always free it.
SrsAutoFree(SrsRtspPacket, cache);
err = rtsp->on_rtp_packet(cache, stream_id);
if (err != srs_success) {
srs_warn("ignore RTP packet err %s", srs_error_desc(err).c_str());
srs_freep(err);
}
return err;
}
SrsRtspAudioCache::SrsRtspAudioCache()
{
dts = 0;
audio = NULL;
payload = NULL;
}
SrsRtspAudioCache::~SrsRtspAudioCache()
{
srs_freep(audio);
srs_freep(payload);
}
SrsRtspJitter::SrsRtspJitter()
{
delta = 0;
previous_timestamp = 0;
pts = 0;
}
SrsRtspJitter::~SrsRtspJitter()
{
}
int64_t SrsRtspJitter::timestamp()
{
return pts;
}
srs_error_t SrsRtspJitter::correct(int64_t& ts)
{
srs_error_t err = srs_success;
if (previous_timestamp == 0) {
previous_timestamp = ts;
}
delta = srs_max(0, (int)(ts - previous_timestamp));
if (delta > 90000) {
delta = 0;
}
previous_timestamp = ts;
ts = pts + delta;
pts = ts;
return err;
}
SrsRtspConn::SrsRtspConn(SrsRtspCaster* c, srs_netfd_t fd, std::string o)
{
output_template = o;
session = "";
video_rtp = NULL;
audio_rtp = NULL;
caster = c;
stfd = fd;
skt = new SrsStSocket();
rtsp = new SrsRtspStack(skt);
trd = new SrsSTCoroutine("rtsp", this);
audio_id = 0;
video_id = 0;
audio_sample_rate = 0;
audio_channel = 0;
req = NULL;
sdk = NULL;
vjitter = new SrsRtspJitter();
ajitter = new SrsRtspJitter();
avc = new SrsRawH264Stream();
aac = new SrsRawAacStream();
acodec = new SrsRawAacStreamCodec();
acache = new SrsRtspAudioCache();
}
SrsRtspConn::~SrsRtspConn()
{
close();
srs_close_stfd(stfd);
srs_freep(video_rtp);
srs_freep(audio_rtp);
srs_freep(trd);
srs_freep(skt);
srs_freep(rtsp);
srs_freep(sdk);
srs_freep(req);
srs_freep(vjitter);
srs_freep(ajitter);
srs_freep(avc);
srs_freep(aac);
srs_freep(acodec);
srs_freep(acache);
}
srs_error_t SrsRtspConn::serve()
{
srs_error_t err = srs_success;
if ((err = skt->initialize(stfd)) != srs_success) {
return srs_error_wrap(err, "socket initialize");
}
if ((err = trd->start()) != srs_success) {
return srs_error_wrap(err, "rtsp connection");
}
return err;
}
std::string SrsRtspConn::remote_ip()
{
// TODO: FIXME: Implement it.
return "";
}
std::string SrsRtspConn::desc()
{
return "RtspConn";
}
const SrsContextId& SrsRtspConn::get_id()
{
return _srs_context->get_id();
}
srs_error_t SrsRtspConn::do_cycle()
{
srs_error_t err = srs_success;
// retrieve ip of client.
int fd = srs_netfd_fileno(stfd);
std::string ip = srs_get_peer_ip(fd);
int port = srs_get_peer_port(fd);
if (ip.empty() && !_srs_config->empty_ip_ok()) {
srs_warn("empty ip for fd=%d", srs_netfd_fileno(stfd));
}
srs_trace("rtsp: serve %s:%d", ip.c_str(), port);
// consume all rtsp messages.
while (true) {
if ((err = trd->pull()) != srs_success) {
return srs_error_wrap(err, "rtsp cycle");
}
SrsRtspRequest* req = NULL;
if ((err = rtsp->recv_message(&req)) != srs_success) {
return srs_error_wrap(err, "recv message");
}
SrsAutoFree(SrsRtspRequest, req);
srs_info("rtsp: got rtsp request");
if (req->is_options()) {
SrsRtspOptionsResponse* res = new SrsRtspOptionsResponse((int)req->seq);
res->session = session;
if ((err = rtsp->send_message(res)) != srs_success) {
return srs_error_wrap(err, "response option");
}
} else if (req->is_announce()) {
if (rtsp_tcUrl.empty()) {
rtsp_tcUrl = req->uri;
}
size_t pos = string::npos;
if ((pos = rtsp_tcUrl.rfind(".sdp")) != string::npos) {
rtsp_tcUrl = rtsp_tcUrl.substr(0, pos);
}
srs_parse_rtmp_url(rtsp_tcUrl, rtsp_tcUrl, rtsp_stream);
srs_assert(req->sdp);
video_id = ::atoi(req->sdp->video_stream_id.c_str());
audio_id = ::atoi(req->sdp->audio_stream_id.c_str());
video_codec = req->sdp->video_codec;
audio_codec = req->sdp->audio_codec;
audio_sample_rate = ::atoi(req->sdp->audio_sample_rate.c_str());
audio_channel = ::atoi(req->sdp->audio_channel.c_str());
h264_sps = req->sdp->video_sps;
h264_pps = req->sdp->video_pps;
aac_specific_config = req->sdp->audio_sh;
srs_trace("rtsp: video(#%d, %s, %s/%s), audio(#%d, %s, %s/%s, %dHZ %dchannels), %s/%s",
video_id, video_codec.c_str(), req->sdp->video_protocol.c_str(), req->sdp->video_transport_format.c_str(),
audio_id, audio_codec.c_str(), req->sdp->audio_protocol.c_str(), req->sdp->audio_transport_format.c_str(),
audio_sample_rate, audio_channel, rtsp_tcUrl.c_str(), rtsp_stream.c_str()
);
SrsRtspResponse* res = new SrsRtspResponse((int)req->seq);
res->session = session;
if ((err = rtsp->send_message(res)) != srs_success) {
return srs_error_wrap(err, "response announce");
}
} else if (req->is_setup()) {
srs_assert(req->transport);
int lpm = 0;
if ((err = caster->alloc_port(&lpm)) != srs_success) {
return srs_error_wrap(err, "alloc port");
}
SrsRtpConn* rtp = NULL;
if (req->stream_id == video_id) {
srs_freep(video_rtp);
rtp = video_rtp = new SrsRtpConn(this, lpm, video_id);
} else {
srs_freep(audio_rtp);
rtp = audio_rtp = new SrsRtpConn(this, lpm, audio_id);
}
if ((err = rtp->listen()) != srs_success) {
return srs_error_wrap(err, "rtp listen");
}
srs_trace("rtsp: #%d %s over %s/%s/%s %s client-port=%d-%d, server-port=%d-%d",
req->stream_id, (req->stream_id == video_id)? "Video":"Audio",
req->transport->transport.c_str(), req->transport->profile.c_str(), req->transport->lower_transport.c_str(),
req->transport->cast_type.c_str(), req->transport->client_port_min, req->transport->client_port_max,
lpm, lpm + 1);
// create session.
if (session.empty()) {
session = "O9EaZ4bf"; // TODO: FIXME: generate session id.
}
SrsRtspSetupResponse* res = new SrsRtspSetupResponse((int)req->seq);
res->client_port_min = req->transport->client_port_min;
res->client_port_max = req->transport->client_port_max;
res->local_port_min = lpm;
res->local_port_max = lpm + 1;
res->session = session;
if ((err = rtsp->send_message(res)) != srs_success) {
return srs_error_wrap(err, "response setup");
}
} else if (req->is_record()) {
SrsRtspResponse* res = new SrsRtspResponse((int)req->seq);
res->session = session;
if ((err = rtsp->send_message(res)) != srs_success) {
return srs_error_wrap(err, "response record");
}
}
}
return err;
}
srs_error_t SrsRtspConn::on_rtp_packet(SrsRtspPacket* pkt, int stream_id)
{
srs_error_t err = srs_success;
// ensure rtmp connected.
if ((err = connect()) != srs_success) {
return srs_error_wrap(err, "connect");
}
if (stream_id == video_id) {
// rtsp tbn is ts tbn.
int64_t pts = pkt->timestamp;
if ((err = vjitter->correct(pts)) != srs_success) {
return srs_error_wrap(err, "jitter");
}
// TODO: FIXME: set dts to pts, please finger out the right dts.
int64_t dts = pts;
return on_rtp_video(pkt, dts, pts);
} else {
// rtsp tbn is ts tbn.
int64_t pts = pkt->timestamp;
if ((err = ajitter->correct(pts)) != srs_success) {
return srs_error_wrap(err, "jitter");
}
return on_rtp_audio(pkt, pts);
}
return err;
}
srs_error_t SrsRtspConn::cycle()
{
// serve the rtsp client.
srs_error_t err = do_cycle();
caster->remove(this);
if (err == srs_success) {
srs_trace("client finished.");
} else if (srs_is_client_gracefully_close(err)) {
srs_warn("client disconnect peer. code=%d", srs_error_code(err));
srs_freep(err);
}
if (video_rtp) {
caster->free_port(video_rtp->port(), video_rtp->port() + 1);
}
if (audio_rtp) {
caster->free_port(audio_rtp->port(), audio_rtp->port() + 1);
}
return err;
}
srs_error_t SrsRtspConn::on_rtp_video(SrsRtspPacket* pkt, int64_t dts, int64_t pts)
{
srs_error_t err = srs_success;
if ((err = kickoff_audio_cache(pkt, dts)) != srs_success) {
return srs_error_wrap(err, "kickoff audio cache");
}
char* bytes = pkt->payload->bytes();
int length = pkt->payload->length();
uint32_t fdts = (uint32_t)(dts / 90);
uint32_t fpts = (uint32_t)(pts / 90);
if ((err = write_h264_ipb_frame(bytes, length, fdts, fpts)) != srs_success) {
return srs_error_wrap(err, "write ibp frame");
}
return err;
}
srs_error_t SrsRtspConn::on_rtp_audio(SrsRtspPacket* pkt, int64_t dts)
{
srs_error_t err = srs_success;
if ((err = kickoff_audio_cache(pkt, dts)) != srs_success) {
return srs_error_wrap(err, "kickoff audio cache");
}
// cache current audio to kickoff.
acache->dts = dts;
acache->audio = pkt->audio;
acache->payload = pkt->payload;
pkt->audio = NULL;
pkt->payload = NULL;
return err;
}
srs_error_t SrsRtspConn::kickoff_audio_cache(SrsRtspPacket* pkt, int64_t dts)
{
srs_error_t err = srs_success;
// nothing to kick off.
if (!acache->payload) {
return err;
}
if (dts - acache->dts > 0 && acache->audio->nb_samples > 0) {
int64_t delta = (dts - acache->dts) / acache->audio->nb_samples;
for (int i = 0; i < acache->audio->nb_samples; i++) {
char* frame = acache->audio->samples[i].bytes;
int nb_frame = acache->audio->samples[i].size;
int64_t timestamp = (acache->dts + delta * i) / 90;
acodec->aac_packet_type = 1;
if ((err = write_audio_raw_frame(frame, nb_frame, acodec, (uint32_t)timestamp)) != srs_success) {
return srs_error_wrap(err, "write audio raw frame");
}
}
}
acache->dts = 0;
srs_freep(acache->audio);
srs_freep(acache->payload);
return err;
}
srs_error_t SrsRtspConn::write_sequence_header()
{
srs_error_t err = srs_success;
// use the current dts.
int64_t dts = vjitter->timestamp() / 90;
// send video sps/pps
if ((err = write_h264_sps_pps((uint32_t)dts, (uint32_t)dts)) != srs_success) {
return srs_error_wrap(err, "write sps/pps");
}
// generate audio sh by audio specific config.
if (aac_specific_config.empty()) {
srs_warn("no audio asc");
return err;
}
std::string sh = aac_specific_config;
SrsFormat* format = new SrsFormat();
SrsAutoFree(SrsFormat, format);
if ((err = format->on_aac_sequence_header((char*)sh.c_str(), (int)sh.length())) != srs_success) {
return srs_error_wrap(err, "on aac sequence header");
}
SrsAudioCodecConfig* dec = format->acodec;
acodec->sound_format = SrsAudioCodecIdAAC;
acodec->sound_type = (dec->aac_channels == 2)? SrsAudioChannelsStereo : SrsAudioChannelsMono;
acodec->sound_size = SrsAudioSampleBits16bit;
acodec->aac_packet_type = 0;
static int srs_aac_srates[] = {
96000, 88200, 64000, 48000,
44100, 32000, 24000, 22050,
16000, 12000, 11025, 8000,
7350, 0, 0, 0
};
switch (srs_aac_srates[dec->aac_sample_rate]) {
case 11025:
acodec->sound_rate = SrsAudioSampleRate11025;
break;
case 22050:
acodec->sound_rate = SrsAudioSampleRate22050;
break;
case 44100:
acodec->sound_rate = SrsAudioSampleRate44100;
break;
default:
break;
};
if ((err = write_audio_raw_frame((char*)sh.data(), (int)sh.length(), acodec, (uint32_t)dts)) != srs_success) {
return srs_error_wrap(err, "write audio raw frame");
}
return err;
}
srs_error_t SrsRtspConn::write_h264_sps_pps(uint32_t dts, uint32_t pts)
{
srs_error_t err = srs_success;
if (h264_sps.empty() || h264_pps.empty()) {
srs_warn("no sps=%dB or pps=%dB", (int)h264_sps.size(), (int)h264_pps.size());
return err;
}
// h264 raw to h264 packet.
std::string sh;
if ((err = avc->mux_sequence_header(h264_sps, h264_pps, dts, pts, sh)) != srs_success) {
return srs_error_wrap(err, "mux sequence header");
}
// h264 packet to flv packet.
int8_t frame_type = SrsVideoAvcFrameTypeKeyFrame;
int8_t avc_packet_type = SrsVideoAvcFrameTraitSequenceHeader;
char* flv = NULL;
int nb_flv = 0;
if ((err = avc->mux_avc2flv(sh, frame_type, avc_packet_type, dts, pts, &flv, &nb_flv)) != srs_success) {
return srs_error_wrap(err, "mux avc to flv");
}
// the timestamp in rtmp message header is dts.
uint32_t timestamp = dts;
if ((err = rtmp_write_packet(SrsFrameTypeVideo, timestamp, flv, nb_flv)) != srs_success) {
return srs_error_wrap(err, "write packet");
}
return err;
}
srs_error_t SrsRtspConn::write_h264_ipb_frame(char* frame, int frame_size, uint32_t dts, uint32_t pts)
{
srs_error_t err = srs_success;
// 5bits, 7.3.1 NAL unit syntax,
// ISO_IEC_14496-10-AVC-2003.pdf, page 44.
// 7: SPS, 8: PPS, 5: I Frame, 1: P Frame
SrsAvcNaluType nal_unit_type = (SrsAvcNaluType)(frame[0] & 0x1f);
// for IDR frame, the frame is keyframe.
SrsVideoAvcFrameType frame_type = SrsVideoAvcFrameTypeInterFrame;
if (nal_unit_type == SrsAvcNaluTypeIDR) {
frame_type = SrsVideoAvcFrameTypeKeyFrame;
}
std::string ibp;
if ((err = avc->mux_ipb_frame(frame, frame_size, ibp)) != srs_success) {
return srs_error_wrap(err, "mux ibp frame");
}
int8_t avc_packet_type = SrsVideoAvcFrameTraitNALU;
char* flv = NULL;
int nb_flv = 0;
if ((err = avc->mux_avc2flv(ibp, frame_type, avc_packet_type, dts, pts, &flv, &nb_flv)) != srs_success) {
return srs_error_wrap(err, "mux avc to flv");
}
// the timestamp in rtmp message header is dts.
uint32_t timestamp = dts;
return rtmp_write_packet(SrsFrameTypeVideo, timestamp, flv, nb_flv);
}
srs_error_t SrsRtspConn::write_audio_raw_frame(char* frame, int frame_size, SrsRawAacStreamCodec* codec, uint32_t dts)
{
srs_error_t err = srs_success;
char* data = NULL;
int size = 0;
if ((err = aac->mux_aac2flv(frame, frame_size, codec, dts, &data, &size)) != srs_success) {
return srs_error_wrap(err, "mux aac to flv");
}
return rtmp_write_packet(SrsFrameTypeAudio, dts, data, size);
}
srs_error_t SrsRtspConn::rtmp_write_packet(char type, uint32_t timestamp, char* data, int size)
{
srs_error_t err = srs_success;
if ((err = connect()) != srs_success) {
return srs_error_wrap(err, "connect");
}
SrsSharedPtrMessage* msg = NULL;
if ((err = srs_rtmp_create_msg(type, timestamp, data, size, sdk->sid(), &msg)) != srs_success) {
return srs_error_wrap(err, "create message");
}
srs_assert(msg);
// send out encoded msg.
if ((err = sdk->send_and_free_message(msg)) != srs_success) {
close();
return srs_error_wrap(err, "write message");
}
return err;
}
srs_error_t SrsRtspConn::connect()
{
srs_error_t err = srs_success;
// Ignore when connected.
if (sdk) {
return err;
}
// generate rtmp url to connect to.
std::string url;
if (!req) {
std::string schema, host, vhost, app, param;
int port;
srs_discovery_tc_url(rtsp_tcUrl, schema, host, vhost, app, rtsp_stream, port, param);
// generate output by template.
std::string output = output_template;
output = srs_string_replace(output, "[app]", app);
output = srs_string_replace(output, "[stream]", rtsp_stream);
url = output;
}
// connect host.
srs_utime_t cto = SRS_CONSTS_RTMP_TIMEOUT;
srs_utime_t sto = SRS_CONSTS_RTMP_PULSE;
sdk = new SrsSimpleRtmpClient(url, cto, sto);
if ((err = sdk->connect()) != srs_success) {
close();
return srs_error_wrap(err, "connect %s failed, cto=%dms, sto=%dms.", url.c_str(), srsu2msi(cto), srsu2msi(sto));
}
// publish.
if ((err = sdk->publish(SRS_CONSTS_RTMP_PROTOCOL_CHUNK_SIZE)) != srs_success) {
close();
return srs_error_wrap(err, "publish %s failed", url.c_str());
}
return write_sequence_header();
}
void SrsRtspConn::close()
{
srs_freep(sdk);
}
SrsRtspCaster::SrsRtspCaster(SrsConfDirective* c)
{
// TODO: FIXME: support reload.
engine = _srs_config->get_stream_caster_engine(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 SrsResourceManager("CRTSP");
}
SrsRtspCaster::~SrsRtspCaster()
{
std::vector<SrsRtspConn*>::iterator it;
for (it = clients.begin(); it != clients.end(); ++it) {
SrsRtspConn* conn = *it;
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)
{
srs_error_t err = srs_success;
// use a pair of port.
for (int i = local_port_min; i < local_port_max - 1; i += 2) {
if (!used_ports[i]) {
used_ports[i] = true;
used_ports[i + 1] = true;
*pport = i;
break;
}
}
srs_trace("rtsp: %s alloc port=%d-%d", engine.c_str(), *pport, *pport + 1);
return err;
}
void SrsRtspCaster::free_port(int lpmin, int lpmax)
{
for (int i = lpmin; i < lpmax; i++) {
used_ports[i] = false;
}
srs_trace("rtsp: %s free rtp port=%d-%d", engine.c_str(), lpmin, lpmax);
}
srs_error_t SrsRtspCaster::on_tcp_client(srs_netfd_t stfd)
{
srs_error_t err = srs_success;
SrsRtspConn* conn = new SrsRtspConn(this, stfd, output);
if ((err = conn->serve()) != srs_success) {
srs_freep(conn);
return srs_error_wrap(err, "serve conn");
}
clients.push_back(conn);
return err;
}
void SrsRtspCaster::remove(SrsRtspConn* conn)
{
std::vector<SrsRtspConn*>::iterator it = find(clients.begin(), clients.end(), conn);
if (it != clients.end()) {
clients.erase(it);
}
srs_info("rtsp: remove connection from caster.");
manager->remove(conn);
}

View file

@ -1,192 +0,0 @@
//
// Copyright (c) 2013-2021 The SRS Authors
//
// SPDX-License-Identifier: MIT
//
#ifndef SRS_APP_RTSP_HPP
#define SRS_APP_RTSP_HPP
#include <srs_core.hpp>
#include <string>
#include <vector>
#include <map>
#include <srs_app_st.hpp>
#include <srs_app_listener.hpp>
#include <srs_service_conn.hpp>
class SrsStSocket;
class SrsRtspConn;
class SrsRtspStack;
class SrsRtspCaster;
class SrsConfDirective;
class SrsRtspPacket;
class SrsRequest;
class SrsStSocket;
class SrsRtmpClient;
class SrsRawH264Stream;
class SrsRawAacStream;
struct SrsRawAacStreamCodec;
class SrsSharedPtrMessage;
class SrsAudioFrame;
class SrsSimpleStream;
class SrsPithyPrint;
class SrsSimpleRtmpClient;
class SrsResourceManager;
// A rtp connection which transport a stream.
class SrsRtpConn: public ISrsUdpHandler
{
private:
SrsPithyPrint* pprint;
SrsUdpListener* listener;
SrsRtspConn* rtsp;
SrsRtspPacket* cache;
int stream_id;
int _port;
public:
SrsRtpConn(SrsRtspConn* r, int p, int sid);
virtual ~SrsRtpConn();
public:
virtual int port();
virtual srs_error_t listen();
// Interface ISrsUdpHandler
public:
virtual srs_error_t on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf);
};
// The audio cache, audio is grouped by frames.
struct SrsRtspAudioCache
{
int64_t dts;
SrsAudioFrame* audio;
SrsSimpleStream* payload;
SrsRtspAudioCache();
virtual ~SrsRtspAudioCache();
};
// The time jitter correct for rtsp.
class SrsRtspJitter
{
private:
int64_t previous_timestamp;
int64_t pts;
int delta;
public:
SrsRtspJitter();
virtual ~SrsRtspJitter();
public:
virtual int64_t timestamp();
virtual srs_error_t correct(int64_t& ts);
};
// The rtsp connection serve the fd.
class SrsRtspConn : public ISrsCoroutineHandler, public ISrsConnection
{
private:
std::string output_template;
std::string rtsp_tcUrl;
std::string rtsp_stream;
private:
std::string session;
// video stream.
int video_id;
std::string video_codec;
SrsRtpConn* video_rtp;
// audio stream.
int audio_id;
std::string audio_codec;
int audio_sample_rate;
int audio_channel;
SrsRtpConn* audio_rtp;
private:
srs_netfd_t stfd;
SrsStSocket* skt;
SrsRtspStack* rtsp;
SrsRtspCaster* caster;
SrsCoroutine* trd;
private:
SrsRequest* req;
SrsSimpleRtmpClient* sdk;
SrsRtspJitter* vjitter;
SrsRtspJitter* ajitter;
private:
SrsRawH264Stream* avc;
std::string h264_sps;
std::string h264_pps;
private:
SrsRawAacStream* aac;
SrsRawAacStreamCodec* acodec;
std::string aac_specific_config;
SrsRtspAudioCache* acache;
public:
SrsRtspConn(SrsRtspCaster* c, srs_netfd_t fd, std::string o);
virtual ~SrsRtspConn();
public:
virtual srs_error_t serve();
// Interface ISrsConnection.
public:
virtual std::string remote_ip();
virtual const SrsContextId& get_id();
virtual std::string desc();
private:
virtual srs_error_t do_cycle();
// internal methods
public:
virtual srs_error_t on_rtp_packet(SrsRtspPacket* pkt, int stream_id);
// Interface ISrsOneCycleThreadHandler
public:
virtual srs_error_t cycle();
private:
virtual srs_error_t on_rtp_video(SrsRtspPacket* pkt, int64_t dts, int64_t pts);
virtual srs_error_t on_rtp_audio(SrsRtspPacket* pkt, int64_t dts);
virtual srs_error_t kickoff_audio_cache(SrsRtspPacket* pkt, int64_t dts);
private:
virtual srs_error_t write_sequence_header();
virtual srs_error_t write_h264_sps_pps(uint32_t dts, uint32_t pts);
virtual srs_error_t write_h264_ipb_frame(char* frame, int frame_size, uint32_t dts, uint32_t pts);
virtual srs_error_t write_audio_raw_frame(char* frame, int frame_size, SrsRawAacStreamCodec* codec, uint32_t dts);
virtual srs_error_t rtmp_write_packet(char type, uint32_t timestamp, char* data, int size);
private:
// Connect to RTMP server.
virtual srs_error_t connect();
// Close the connection to RTMP server.
virtual void close();
};
// The caster for rtsp.
class SrsRtspCaster : public ISrsTcpHandler
{
private:
std::string engine;
std::string output;
int local_port_min;
int local_port_max;
// The key: port, value: whether used.
std::map<int, bool> used_ports;
private:
std::vector<SrsRtspConn*> clients;
SrsResourceManager* manager;
public:
SrsRtspCaster(SrsConfDirective* c);
virtual ~SrsRtspCaster();
public:
// Alloc a rtp port from local ports pool.
// @param pport output the rtp port.
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);
// internal methods.
public:
virtual void remove(SrsRtspConn* conn);
};
#endif

View file

@ -16,7 +16,6 @@
class SrsConfDirective;
// The security apply on vhost.
// @see https://github.com/ossrs/srs/issues/211
class SrsSecurity
{
public:

View file

@ -30,7 +30,6 @@ using namespace std;
#include <srs_app_utility.hpp>
#include <srs_app_heartbeat.hpp>
#include <srs_app_mpegts_udp.hpp>
#include <srs_app_rtsp.hpp>
#include <srs_app_statistic.hpp>
#include <srs_app_caster_flv.hpp>
#include <srs_kernel_consts.hpp>
@ -53,8 +52,6 @@ std::string srs_listener_type2string(SrsListenerType type)
return "HTTP-Server";
case SrsListenerMpegTsOverUdp:
return "MPEG-TS over UDP";
case SrsListenerRtsp:
return "RTSP";
case SrsListenerFlv:
return "HTTP-FLV";
default:
@ -119,62 +116,6 @@ srs_error_t SrsBufferListener::on_tcp_client(srs_netfd_t stfd)
return srs_success;
}
SrsRtspListener::SrsRtspListener(SrsServer* svr, SrsListenerType t, SrsConfDirective* c) : SrsListener(svr, t)
{
listener = NULL;
// the caller already ensure the type is ok,
// we just assert here for unknown stream caster.
srs_assert(type == SrsListenerRtsp);
if (type == SrsListenerRtsp) {
caster = new SrsRtspCaster(c);
// TODO: FIXME: Must check error.
caster->initialize();
}
}
SrsRtspListener::~SrsRtspListener()
{
srs_freep(caster);
srs_freep(listener);
}
srs_error_t SrsRtspListener::listen(string i, int p)
{
srs_error_t err = srs_success;
// the caller already ensure the type is ok,
// we just assert here for unknown stream caster.
srs_assert(type == SrsListenerRtsp);
ip = i;
port = p;
srs_freep(listener);
listener = new SrsTcpListener(this, ip, port);
if ((err = listener->listen()) != srs_success) {
return srs_error_wrap(err, "rtsp listen %s:%d", ip.c_str(), port);
}
string v = srs_listener_type2string(type);
srs_trace("%s listen at tcp://%s:%d, fd=%d", v.c_str(), ip.c_str(), port, listener->fd());
return err;
}
srs_error_t SrsRtspListener::on_tcp_client(srs_netfd_t stfd)
{
srs_error_t err = caster->on_tcp_client(stfd);
if (err != srs_success) {
srs_warn("accept client failed, err is %s", srs_error_desc(err).c_str());
srs_freep(err);
}
return srs_success;
}
SrsHttpFlvListener::SrsHttpFlvListener(SrsServer* svr, SrsListenerType t, SrsConfDirective* c) : SrsListener(svr, t)
{
listener = NULL;
@ -629,7 +570,6 @@ void SrsServer::dispose()
close_listeners(SrsListenerHttpStream);
close_listeners(SrsListenerHttpsStream);
close_listeners(SrsListenerMpegTsOverUdp);
close_listeners(SrsListenerRtsp);
close_listeners(SrsListenerFlv);
// Fast stop to notify FFMPEG to quit, wait for a while then fast kill.
@ -656,7 +596,6 @@ void SrsServer::gracefully_dispose()
close_listeners(SrsListenerHttpStream);
close_listeners(SrsListenerHttpsStream);
close_listeners(SrsListenerMpegTsOverUdp);
close_listeners(SrsListenerRtsp);
close_listeners(SrsListenerFlv);
srs_trace("listeners closed");
@ -1359,9 +1298,6 @@ srs_error_t SrsServer::listen_stream_caster()
std::string caster = _srs_config->get_stream_caster_engine(stream_caster);
if (srs_stream_caster_is_udp(caster)) {
listener = new SrsUdpCasterListener(this, SrsListenerMpegTsOverUdp, stream_caster);
} else if (srs_stream_caster_is_rtsp(caster)) {
srs_warn("It's deprecated and will be removed in the future, see https://github.com/ossrs/srs/issues/2304#issuecomment-826009290");
listener = new SrsRtspListener(this, SrsListenerRtsp, stream_caster);
} else if (srs_stream_caster_is_flv(caster)) {
listener = new SrsHttpFlvListener(this, SrsListenerFlv, stream_caster);
} else {

View file

@ -34,7 +34,6 @@ class ISrsUdpHandler;
class SrsUdpListener;
class SrsTcpListener;
class SrsAppCasterFlv;
class SrsRtspCaster;
class SrsResourceManager;
class SrsLatestVersion;
@ -50,8 +49,6 @@ enum SrsListenerType
SrsListenerHttpStream = 2,
// UDP stream, MPEG-TS over udp.
SrsListenerMpegTsOverUdp = 3,
// TCP stream, RTSP stream.
SrsListenerRtsp = 4,
// TCP stream, FLV stream over HTTP.
SrsListenerFlv = 5,
// HTTPS api,
@ -92,22 +89,6 @@ public:
virtual srs_error_t on_tcp_client(srs_netfd_t stfd);
};
// A TCP listener, for rtsp server.
class SrsRtspListener : public SrsListener, public ISrsTcpHandler
{
private:
SrsTcpListener* listener;
SrsRtspCaster* caster;
public:
SrsRtspListener(SrsServer* svr, SrsListenerType t, SrsConfDirective* c);
virtual ~SrsRtspListener();
public:
virtual srs_error_t listen(std::string i, int p);
// Interface ISrsTcpHandler
public:
virtual srs_error_t on_tcp_client(srs_netfd_t stfd);
};
// A TCP listener, for flv stream server.
class SrsHttpFlvListener : public SrsListener, public ISrsTcpHandler
{

View file

@ -9,6 +9,6 @@
#define VERSION_MAJOR 4
#define VERSION_MINOR 0
#define VERSION_REVISION 167
#define VERSION_REVISION 171
#endif

View file

@ -1078,10 +1078,57 @@ srs_error_t SrsFormat::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp)
if ((err = srs_avc_nalu_read_uev(&bs, pic_height_in_map_units_minus1)) != srs_success) {
return srs_error_wrap(err, "read pic_height_in_map_units_minus1");;
}
vcodec->width = (int)(pic_width_in_mbs_minus1 + 1) * 16;
vcodec->height = (int)(pic_height_in_map_units_minus1 + 1) * 16;
int8_t frame_mbs_only_flag = -1;
if ((err = srs_avc_nalu_read_bit(&bs, frame_mbs_only_flag)) != srs_success) {
return srs_error_wrap(err, "read frame_mbs_only_flag");;
}
if(!frame_mbs_only_flag) {
/* Skip mb_adaptive_frame_field_flag */
int8_t mb_adaptive_frame_field_flag = -1;
if ((err = srs_avc_nalu_read_bit(&bs, mb_adaptive_frame_field_flag)) != srs_success) {
return srs_error_wrap(err, "read mb_adaptive_frame_field_flag");;
}
}
/* Skip direct_8x8_inference_flag */
int8_t direct_8x8_inference_flag = -1;
if ((err = srs_avc_nalu_read_bit(&bs, direct_8x8_inference_flag)) != srs_success) {
return srs_error_wrap(err, "read direct_8x8_inference_flag");;
}
/* We need the following value to evaluate offsets, if any */
int8_t frame_cropping_flag = -1;
if ((err = srs_avc_nalu_read_bit(&bs, frame_cropping_flag)) != srs_success) {
return srs_error_wrap(err, "read frame_cropping_flag");;
}
int32_t frame_crop_left_offset = 0, frame_crop_right_offset = 0,
frame_crop_top_offset = 0, frame_crop_bottom_offset = 0;
if(frame_cropping_flag) {
if ((err = srs_avc_nalu_read_uev(&bs, frame_crop_left_offset)) != srs_success) {
return srs_error_wrap(err, "read frame_crop_left_offset");;
}
if ((err = srs_avc_nalu_read_uev(&bs, frame_crop_right_offset)) != srs_success) {
return srs_error_wrap(err, "read frame_crop_right_offset");;
}
if ((err = srs_avc_nalu_read_uev(&bs, frame_crop_top_offset)) != srs_success) {
return srs_error_wrap(err, "read frame_crop_top_offset");;
}
if ((err = srs_avc_nalu_read_uev(&bs, frame_crop_bottom_offset)) != srs_success) {
return srs_error_wrap(err, "read frame_crop_bottom_offset");;
}
}
/* Skip vui_parameters_present_flag */
int8_t vui_parameters_present_flag = -1;
if ((err = srs_avc_nalu_read_bit(&bs, vui_parameters_present_flag)) != srs_success) {
return srs_error_wrap(err, "read vui_parameters_present_flag");;
}
vcodec->width = ((pic_width_in_mbs_minus1 + 1) * 16) - frame_crop_left_offset * 2 - frame_crop_right_offset * 2;
vcodec->height = ((2 - frame_mbs_only_flag) * (pic_height_in_map_units_minus1 + 1) * 16) \
- (frame_crop_top_offset * 2) - (frame_crop_bottom_offset * 2);
return err;
}

View file

@ -6,7 +6,6 @@
#include <srs_kernel_mp3.hpp>
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213
#ifndef _WIN32
#include <unistd.h>
#endif

View file

@ -6,7 +6,6 @@
#include <srs_kernel_utility.hpp>
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213
#ifndef _WIN32
#include <unistd.h>
#include <netdb.h>
@ -120,7 +119,6 @@ srs_utime_t srs_update_system_time()
return -1;
}
// @see: https://github.com/ossrs/srs/issues/35
// we must convert the tv_sec/tv_usec to int64_t.
int64_t now_us = ((int64_t)now.tv_sec) * 1000 * 1000 + (int64_t)now.tv_usec;
@ -140,7 +138,6 @@ srs_utime_t srs_update_system_time()
diff = srs_max(0, diff);
if (diff < 0 || diff > 1000 * SYS_TIME_RESOLUTION_US) {
srs_warn("clock jump, history=%" PRId64 "us, now=%" PRId64 "us, diff=%" PRId64 "us", _srs_system_time_us_cache, now_us, diff);
// @see: https://github.com/ossrs/srs/issues/109
_srs_system_time_startup_time += diff;
}
@ -580,7 +577,6 @@ int srs_do_create_dir_recursively(string dir)
}
// create curren dir.
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213
#ifdef _WIN32
if (::_mkdir(dir.c_str()) < 0) {
#else

View file

@ -49,6 +49,7 @@ using namespace std;
// pre-declare
srs_error_t run_directly_or_daemon();
srs_error_t srs_detect_docker();
srs_error_t run_hybrid_server();
void show_macro_features();
@ -95,6 +96,11 @@ srs_error_t do_main(int argc, char** argv)
#ifdef SRS_GPERF_MP
#warning "gmp is not used for memory leak, please use gmc instead."
#endif
// Ignore any error while detecting docker.
if ((err = srs_detect_docker()) != srs_success) {
srs_error_reset(err);
}
// never use srs log(srs_trace, srs_error, etc) before config parse the option,
// which will load the log config and apply it.
@ -378,11 +384,6 @@ srs_error_t run_directly_or_daemon()
{
srs_error_t err = srs_success;
// Ignore any error while detecting docker.
if ((err = srs_detect_docker()) != srs_success) {
srs_error_reset(err);
}
// Load daemon from config, disable it for docker.
// @see https://github.com/ossrs/srs/issues/1594
bool run_as_daemon = _srs_config->get_daemon();

View file

@ -167,7 +167,6 @@ srs_error_t SrsFastStream::grow(ISrsReader* reader, int required_size)
* to improve read performance, merge some packets then read,
* when it on and read small bytes, we sleep to wait more data.,
* that is, we merge some data to read together.
* @see https://github.com/ossrs/srs/issues/241
*/
if (merged_read && _handler) {
_handler->on_read(nread);

View file

@ -6,7 +6,6 @@
#include <srs_protocol_utility.hpp>
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213
#ifndef _WIN32
#include <unistd.h>
#endif
@ -349,7 +348,6 @@ srs_error_t srs_write_large_iovs(ISrsProtocolReadWriter* skt, iovec* iovs, int s
srs_error_t err = srs_success;
// the limits of writev iovs.
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213
#ifndef _WIN32
// for linux, generally it's 1024.
static int limits = (int)sysconf(_SC_IOV_MAX);

View file

@ -9,7 +9,6 @@
#include <srs_core.hpp>
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213
#ifndef _WIN32
#include <sys/uio.h>
#endif

View file

@ -281,7 +281,6 @@ srs_error_t SrsRawAacStream::adts_demux(SrsBuffer* stream, char** pframe, int* p
// decode the ADTS.
// @see ISO_IEC_13818-7-AAC-2004.pdf, page 26
// 6.2 Audio Data Transport Stream, ADTS
// @see https://github.com/ossrs/srs/issues/212#issuecomment-64145885
// byte_alignment()
// adts_fixed_header:
@ -342,7 +341,7 @@ srs_error_t SrsRawAacStream::adts_demux(SrsBuffer* stream, char** pframe, int* p
int8_t channel_configuration = (sfiv >> 6) & 0x07;
/*int8_t original = (sfiv >> 5) & 0x01;*/
/*int8_t home = (sfiv >> 4) & 0x01;*/
//int8_t Emphasis; @remark, Emphasis is removed, @see https://github.com/ossrs/srs/issues/212#issuecomment-64154736
//int8_t Emphasis; @remark, Emphasis is removed
// 4bits left.
// adts_variable_header(), 1.A.2.2.2 Variable Header of ADTS
// copyright_identification_bit 1 bslbf

View file

@ -571,7 +571,6 @@ namespace srs_internal
}
// directly generate the public key.
// @see: https://github.com/ossrs/srs/issues/148
int pkey_size = 128;
if ((err = dh.copy_shared_key(c1->get_key(), 128, key.key, pkey_size)) != srs_success) {
return srs_error_wrap(err, "copy shared key");

View file

@ -1036,7 +1036,6 @@ srs_error_t SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt)
// 0x04 where: message_type=4(protocol control user-control message)
// 0x00 0x06 where: event Ping(0x06)
// 0x00 0x00 0x0d 0x0f where: event data 4bytes ping timestamp.
// @see: https://github.com/ossrs/srs/issues/98
if (fmt == RTMP_FMT_TYPE1) {
srs_warn("fresh chunk starts with fmt=1");
} else {
@ -1175,7 +1174,6 @@ srs_error_t SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt)
pp[0] = *p++;
// always use 31bits timestamp, for some server may use 32bits extended timestamp.
// @see https://github.com/ossrs/srs/issues/111
timestamp &= 0x7fffffff;
/**

View file

@ -13,7 +13,6 @@
#include <vector>
#include <string>
// For srs-librtmp, @see https://github.com/ossrs/srs/issues/213
#ifndef _WIN32
#include <sys/uio.h>
#endif
@ -161,7 +160,6 @@ private:
std::map<int, SrsChunkStream*> chunk_streams;
// Cache some frequently used chunk header.
// cs_cache, the chunk stream cache.
// @see https://github.com/ossrs/srs/issues/249
SrsChunkStream** cs_cache;
// The bytes buffer cache, recv from skt, provide services for stream.
SrsFastStream* in_buffer;
@ -179,7 +177,6 @@ private:
bool show_debug_info;
// Whether auto response when recv messages.
// default to true for it's very easy to use the protocol stack.
// @see: https://github.com/ossrs/srs/issues/217
bool auto_response_when_recv;
// When not auto response message, manual flush the messages in queue.
std::vector<SrsPacket*> manual_response_queue;
@ -208,7 +205,6 @@ public:
public:
// Set the auto response message when recv for protocol stack.
// @param v, whether auto response message when recv message.
// @see: https://github.com/ossrs/srs/issues/217
virtual void set_auto_response(bool v);
// Flush for manual response when the auto response is disabled
// by set_auto_response(false), we default use auto response, so donot
@ -222,13 +218,11 @@ public:
// that is, we merge some data to read together.
// @param v true to ename merged read.
// @param handler the handler when merge read is enabled.
// @see https://github.com/ossrs/srs/issues/241
virtual void set_merge_read(bool v, IMergeReadHandler* handler);
// Create buffer with specifeid size.
// @param buffer the size of buffer.
// @remark when MR(SRS_PERF_MERGED_READ) disabled, always set to 8K.
// @remark when buffer changed, the previous ptr maybe invalid.
// @see https://github.com/ossrs/srs/issues/241
virtual void set_recv_buffer(int buffer_size);
#endif
public:
@ -429,7 +423,6 @@ public:
std::string stream;
// For play live stream,
// used to specified the stop when exceed the duration.
// @see https://github.com/ossrs/srs/issues/45
// in srs_utime_t.
srs_utime_t duration;
// The token in the connect request,
@ -620,7 +613,6 @@ public:
public:
// Set the auto response message when recv for protocol stack.
// @param v, whether auto response message when recv message.
// @see: https://github.com/ossrs/srs/issues/217
virtual void set_auto_response(bool v);
#ifdef SRS_PERF_MERGED_READ
// To improve read performance, merge some packets then read,
@ -628,13 +620,11 @@ public:
// that is, we merge some data to read together.
// @param v true to ename merged read.
// @param handler the handler when merge read is enabled.
// @see https://github.com/ossrs/srs/issues/241
virtual void set_merge_read(bool v, IMergeReadHandler* handler);
// Create buffer with specifeid size.
// @param buffer the size of buffer.
// @remark when MR(SRS_PERF_MERGED_READ) disabled, always set to 8K.
// @remark when buffer changed, the previous ptr maybe invalid.
// @see https://github.com/ossrs/srs/issues/241
virtual void set_recv_buffer(int buffer_size);
#endif
// To set/get the recv timeout in srs_utime_t.
@ -675,7 +665,6 @@ public:
// @param stream_id, the stream id of packet to send over, 0 for control message.
//
// @remark performance issue, to support 6k+ 250kbps client,
// @see https://github.com/ossrs/srs/issues/194
virtual srs_error_t send_and_free_messages(SrsSharedPtrMessage** msgs, int nb_msgs, int stream_id);
// Send the RTMP packet and always free it.
// user must never free or use the packet after this method,
@ -1336,11 +1325,9 @@ public:
// Name of command. Set to "|RtmpSampleAccess".
std::string command_name;
// Whether allow access the sample of video.
// @see: https://github.com/ossrs/srs/issues/49
// @see: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetStream.html#videoSampleAccess
bool video_sample_access;
// Whether allow access the sample of audio.
// @see: https://github.com/ossrs/srs/issues/49
// @see: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetStream.html#audioSampleAccess
bool audio_sample_access;
public:

View file

@ -97,7 +97,6 @@ srs_error_t SrsBasicRtmpClient::do_connect_app(string local_ip, bool debug)
}
// notify server the edge identity,
// @see https://github.com/ossrs/srs/issues/147
SrsAmf0Object* data = req->args;
data->set("srs_sig", SrsAmf0Any::str(RTMP_SIG_SRS_KEY));
data->set("srs_server", SrsAmf0Any::str(RTMP_SIG_SRS_SERVER));
@ -121,7 +120,6 @@ srs_error_t SrsBasicRtmpClient::do_connect_app(string local_ip, bool debug)
req->tcUrl = tc_url;
// upnode server identity will show in the connect_app of client.
// @see https://github.com/ossrs/srs/issues/160
// the debug_srs_upnode is config in vhost and default to true.
SrsServerInfo si;
if ((err = client->connect_app(req->app, tc_url, req, debug, &si)) != srs_success) {

View file

@ -41,7 +41,6 @@ srs_error_t srs_st_init()
{
#ifdef __linux__
// check epoll, some old linux donot support epoll.
// @see https://github.com/ossrs/srs/issues/162
if (!srs_st_epoll_is_supported()) {
return srs_error_new(ERROR_ST_SET_EPOLL, "linux epoll disabled");
}
@ -510,7 +509,6 @@ srs_error_t SrsStSocket::read(void* buf, size_t size, ssize_t* nread)
// (a value of 0 means the network connection is closed or end of file is reached).
// Otherwise, a value of -1 is returned and errno is set to indicate the error.
if (nb_read <= 0) {
// @see https://github.com/ossrs/srs/issues/200
if (nb_read < 0 && errno == ETIME) {
return srs_error_new(ERROR_SOCKET_TIMEOUT, "timeout %d ms", srsu2msi(rtm));
}
@ -546,7 +544,6 @@ srs_error_t SrsStSocket::read_fully(void* buf, size_t size, ssize_t* nread)
// (a value less than nbyte means the network connection is closed or end of file is reached)
// Otherwise, a value of -1 is returned and errno is set to indicate the error.
if (nb_read != (ssize_t)size) {
// @see https://github.com/ossrs/srs/issues/200
if (nb_read < 0 && errno == ETIME) {
return srs_error_new(ERROR_SOCKET_TIMEOUT, "timeout %d ms", srsu2msi(rtm));
}
@ -581,7 +578,6 @@ srs_error_t SrsStSocket::write(void* buf, size_t size, ssize_t* nwrite)
// On success a non-negative integer equal to nbyte is returned.
// Otherwise, a value of -1 is returned and errno is set to indicate the error.
if (nb_write <= 0) {
// @see https://github.com/ossrs/srs/issues/200
if (nb_write < 0 && errno == ETIME) {
return srs_error_new(ERROR_SOCKET_TIMEOUT, "write timeout %d ms", srsu2msi(stm));
}
@ -612,7 +608,6 @@ srs_error_t SrsStSocket::writev(const iovec *iov, int iov_size, ssize_t* nwrite)
// On success a non-negative integer equal to nbyte is returned.
// Otherwise, a value of -1 is returned and errno is set to indicate the error.
if (nb_write <= 0) {
// @see https://github.com/ossrs/srs/issues/200
if (nb_write < 0 && errno == ETIME) {
return srs_error_new(ERROR_SOCKET_TIMEOUT, "writev timeout %d ms", srsu2msi(stm));
}

View file

@ -2162,9 +2162,6 @@ VOID TEST(ConfigUnitTest, OperatorEquals)
EXPECT_TRUE(srs_stream_caster_is_udp("mpegts_over_udp"));
EXPECT_FALSE(srs_stream_caster_is_udp("xxx"));
EXPECT_TRUE(srs_stream_caster_is_rtsp("rtsp"));
EXPECT_FALSE(srs_stream_caster_is_rtsp("xxx"));
EXPECT_TRUE(srs_stream_caster_is_flv("flv"));
EXPECT_FALSE(srs_stream_caster_is_flv("xxx"));

View file

@ -727,7 +727,6 @@ VOID TEST(ProtocolStackTest, ProtocolRecvMessage)
// 0x04 where: message_type=4(protocol control user-control message)
// 0x00 0x06 where: event Ping(0x06)
// 0x00 0x00 0x0d 0x0f where: event data 4bytes ping timestamp.
// @see: https://github.com/ossrs/srs/issues/98
VOID TEST(ProtocolStackTest, ProtocolRecvMessageBug98)
{
MockBufferIO bio;
@ -3824,7 +3823,6 @@ VOID TEST(ProtocolStackTest, ProtocolRecvExtTimeMessage2)
* always use 31bits timestamp.
*/
// always use 31bits timestamp, for some server may use 32bits extended timestamp.
// @see https://github.com/ossrs/srs/issues/111
VOID TEST(ProtocolStackTest, ProtocolRecvExtTimeMessage3)
{
MockBufferIO bio;