mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
Squash: Fix bugs
This commit is contained in:
parent
10d188faab
commit
716e578a19
382 changed files with 170096 additions and 220 deletions
|
@ -1982,23 +1982,22 @@ srs_error_t SrsConfig::parse_options(int argc, char** argv)
|
|||
srs_trace(_srs_version);
|
||||
|
||||
// Try config files as bellow:
|
||||
// config_file Specified by user, like conf/srs.conf
|
||||
// try_docker_config Guess by SRS, like conf/docker.conf
|
||||
// try_fhs_config For FHS, try /etc/srs/srs.conf first, @see https://github.com/ossrs/srs/pull/2711
|
||||
if (!srs_path_exists(config_file)) {
|
||||
// User specified config(not empty), like user/docker.conf
|
||||
// If user specified *docker.conf, try *srs.conf, like user/srs.conf
|
||||
// Try the default srs config, defined as SRS_CONF_DEFAULT_COFNIG_FILE, like conf/srs.conf
|
||||
// Try config for FHS, like /etc/srs/srs.conf @see https://github.com/ossrs/srs/pull/2711
|
||||
if (true) {
|
||||
vector<string> try_config_files;
|
||||
if (!config_file.empty()) {
|
||||
try_config_files.push_back(config_file);
|
||||
if (srs_string_ends_with(config_file, "docker.conf")) {
|
||||
try_config_files.push_back(srs_string_replace(config_file, "docker.conf", "srs.conf"));
|
||||
}
|
||||
}
|
||||
if (srs_string_ends_with(config_file, "docker.conf")) {
|
||||
try_config_files.push_back(srs_string_replace(config_file, "docker.conf", "srs.conf"));
|
||||
}
|
||||
try_config_files.push_back(SRS_CONF_DEFAULT_COFNIG_FILE);
|
||||
if (srs_string_ends_with(SRS_CONF_DEFAULT_COFNIG_FILE, "docker.conf")) {
|
||||
try_config_files.push_back(srs_string_replace(SRS_CONF_DEFAULT_COFNIG_FILE, "docker.conf", "srs.conf"));
|
||||
}
|
||||
try_config_files.push_back("/etc/srs/srs.conf");
|
||||
|
||||
// Match the first exists file.
|
||||
string exists_config_file;
|
||||
for (int i = 0; i < (int) try_config_files.size(); i++) {
|
||||
string try_config_file = try_config_files.at(i);
|
||||
|
|
|
@ -63,17 +63,17 @@ void SrsHlsSegment::config_cipher(unsigned char* key,unsigned char* iv)
|
|||
|
||||
SrsEncFileWriter* fw = (SrsEncFileWriter*)writer;
|
||||
fw->config_cipher(key, iv);
|
||||
}
|
||||
|
||||
srs_error_t SrsHlsSegment::rename()
|
||||
}
|
||||
|
||||
srs_error_t SrsHlsSegment::rename()
|
||||
{
|
||||
if (true) {
|
||||
std::stringstream ss;
|
||||
ss << srsu2msi(duration());
|
||||
uri = srs_string_replace(uri, "[duration]", ss.str());
|
||||
}
|
||||
|
||||
return SrsFragment::rename();
|
||||
}
|
||||
|
||||
return SrsFragment::rename();
|
||||
}
|
||||
|
||||
SrsDvrAsyncCallOnHls::SrsDvrAsyncCallOnHls(SrsContextId c, SrsRequest* r, string p, string t, string m, string mu, int s, srs_utime_t d)
|
||||
|
@ -1355,7 +1355,7 @@ void SrsHls::hls_show_mux_log()
|
|||
// the run time is not equals to stream time,
|
||||
// @see: https://github.com/ossrs/srs/issues/81#issuecomment-48100994
|
||||
// it's ok.
|
||||
srs_trace("-> " SRS_CONSTS_LOG_HLS " time=%dms, sno=%d, ts=%s, dur=%.2f, dva=%dp",
|
||||
srs_trace("-> " SRS_CONSTS_LOG_HLS " time=%dms, sno=%d, ts=%s, dur=%dms, dva=%dp",
|
||||
pprint->age(), controller->sequence_no(), controller->ts_url().c_str(),
|
||||
srsu2msi(controller->duration()), controller->deviation());
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ SrsVodStream::~SrsVodStream()
|
|||
map_ctx_info_.clear();
|
||||
}
|
||||
|
||||
srs_error_t SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int offset)
|
||||
srs_error_t SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int64_t offset)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
@ -69,7 +69,7 @@ srs_error_t SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMe
|
|||
}
|
||||
|
||||
if (offset > fs->filesize()) {
|
||||
return srs_error_new(ERROR_HTTP_REMUX_OFFSET_OVERFLOW, "http flv streaming %s overflow. size=%" PRId64 ", offset=%d",
|
||||
return srs_error_new(ERROR_HTTP_REMUX_OFFSET_OVERFLOW, "http flv streaming %s overflow. size=%" PRId64 ", offset=%" PRId64,
|
||||
fullpath.c_str(), fs->filesize(), offset);
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ srs_error_t SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMe
|
|||
int64_t left = fs->filesize() - offset;
|
||||
|
||||
// write http header for ts.
|
||||
w->header()->set_content_length((int)(sizeof(flv_header) + sh_size + left));
|
||||
w->header()->set_content_length(sizeof(flv_header) + sh_size + left);
|
||||
w->header()->set_content_type("video/x-flv");
|
||||
w->write_header(SRS_CONSTS_HTTP_OK);
|
||||
|
||||
|
@ -130,14 +130,14 @@ srs_error_t SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMe
|
|||
}
|
||||
|
||||
// send data
|
||||
if ((err = copy(w, fs, r, (int)left)) != srs_success) {
|
||||
return srs_error_wrap(err, "read flv=%s size=%d", fullpath.c_str(), (int)left);
|
||||
if ((err = copy(w, fs, r, left)) != srs_success) {
|
||||
return srs_error_wrap(err, "read flv=%s size=%" PRId64, fullpath.c_str(), left);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsVodStream::serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int start, int end)
|
||||
srs_error_t SrsVodStream::serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int64_t start, int64_t end)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
@ -154,7 +154,7 @@ srs_error_t SrsVodStream::serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMe
|
|||
|
||||
// parse -1 to whole file.
|
||||
if (end == -1) {
|
||||
end = (int)(fs->filesize() - 1);
|
||||
end = fs->filesize() - 1;
|
||||
}
|
||||
|
||||
if (end > fs->filesize() || start > end || end < 0) {
|
||||
|
@ -180,8 +180,8 @@ srs_error_t SrsVodStream::serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMe
|
|||
fs->seek2(start);
|
||||
|
||||
// send data
|
||||
if ((err = copy(w, fs, r, (int)left)) != srs_success) {
|
||||
return srs_error_wrap(err, "read mp4=%s size=%d", fullpath.c_str(), (int)left);
|
||||
if ((err = copy(w, fs, r, left)) != srs_success) {
|
||||
return srs_error_wrap(err, "read mp4=%s size=%" PRId64, fullpath.c_str(), left);
|
||||
}
|
||||
|
||||
return err;
|
||||
|
|
|
@ -11,10 +11,10 @@
|
|||
|
||||
#include <srs_app_http_conn.hpp>
|
||||
|
||||
struct SrsM3u8CtxInfo
|
||||
{
|
||||
srs_utime_t request_time;
|
||||
SrsRequest* req;
|
||||
struct SrsM3u8CtxInfo
|
||||
{
|
||||
srs_utime_t request_time;
|
||||
SrsRequest* req;
|
||||
};
|
||||
|
||||
// The flv vod stream supports flv?start=offset-bytes.
|
||||
|
@ -30,8 +30,8 @@ public:
|
|||
SrsVodStream(std::string root_dir);
|
||||
virtual ~SrsVodStream();
|
||||
protected:
|
||||
virtual srs_error_t serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int offset);
|
||||
virtual srs_error_t serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int start, int end);
|
||||
virtual srs_error_t serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int64_t offset);
|
||||
virtual srs_error_t serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int64_t start, int64_t end);
|
||||
virtual srs_error_t serve_m3u8_ctx(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath);
|
||||
private:
|
||||
virtual bool ctx_is_exist(std::string ctx);
|
||||
|
|
|
@ -195,17 +195,20 @@ srs_error_t SrsHybridServer::run()
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// Wait for all servers which need to do cleanup.
|
||||
SrsWaitGroup wg;
|
||||
|
||||
vector<ISrsHybridServer*>::iterator it;
|
||||
for (it = servers.begin(); it != servers.end(); ++it) {
|
||||
ISrsHybridServer* server = *it;
|
||||
|
||||
if ((err = server->run()) != srs_success) {
|
||||
if ((err = server->run(&wg)) != srs_success) {
|
||||
return srs_error_wrap(err, "run server");
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for all server to quit.
|
||||
srs_usleep(SRS_UTIME_NO_TIMEOUT);
|
||||
wg.wait();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
class SrsServer;
|
||||
class SrsServerAdapter;
|
||||
class SrsWaitGroup;
|
||||
|
||||
// The hibrid server interfaces, we could register many servers.
|
||||
class ISrsHybridServer
|
||||
|
@ -26,7 +27,7 @@ public:
|
|||
// Only ST initialized before each server, we could fork processes as such.
|
||||
virtual srs_error_t initialize() = 0;
|
||||
// Run each server, should never block except the SRS master server.
|
||||
virtual srs_error_t run() = 0;
|
||||
virtual srs_error_t run(SrsWaitGroup* wg) = 0;
|
||||
// Stop each server, should do cleanup, for example, kill processes forked by server.
|
||||
virtual void stop() = 0;
|
||||
};
|
||||
|
|
|
@ -2877,7 +2877,12 @@ srs_error_t SrsRtcConnection::negotiate_publish_capability(SrsRtcUserConfig* ruc
|
|||
break;
|
||||
}
|
||||
} else if (remote_media_desc.is_video() && ruc->codec_ == "av1") {
|
||||
std::vector<SrsMediaPayloadType> payloads = remote_media_desc.find_media_with_encoding_name("AV1X");
|
||||
std::vector<SrsMediaPayloadType> payloads = remote_media_desc.find_media_with_encoding_name("AV1");
|
||||
if (payloads.empty()) {
|
||||
// Be compatible with the Chrome M96, still check the AV1X encoding name
|
||||
// @see https://bugs.chromium.org/p/webrtc/issues/detail?id=13166
|
||||
payloads = remote_media_desc.find_media_with_encoding_name("AV1X");
|
||||
}
|
||||
if (payloads.empty()) {
|
||||
return srs_error_new(ERROR_RTC_SDP_EXCHANGE, "no found valid AV1 payload type");
|
||||
}
|
||||
|
@ -3188,13 +3193,23 @@ srs_error_t SrsRtcConnection::negotiate_play_capability(SrsRtcUserConfig* ruc, s
|
|||
remote_payload = payloads.at(0);
|
||||
track_descs = source->get_track_desc("audio", "opus");
|
||||
} else if (remote_media_desc.is_video() && ruc->codec_ == "av1") {
|
||||
std::vector<SrsMediaPayloadType> payloads = remote_media_desc.find_media_with_encoding_name("AV1X");
|
||||
std::vector<SrsMediaPayloadType> payloads = remote_media_desc.find_media_with_encoding_name("AV1");
|
||||
if (payloads.empty()) {
|
||||
// Be compatible with the Chrome M96, still check the AV1X encoding name
|
||||
// @see https://bugs.chromium.org/p/webrtc/issues/detail?id=13166
|
||||
payloads = remote_media_desc.find_media_with_encoding_name("AV1X");
|
||||
}
|
||||
if (payloads.empty()) {
|
||||
return srs_error_new(ERROR_RTC_SDP_EXCHANGE, "no found valid AV1 payload type");
|
||||
}
|
||||
|
||||
remote_payload = payloads.at(0);
|
||||
track_descs = source->get_track_desc("video", "AV1X");
|
||||
track_descs = source->get_track_desc("video", "AV1");
|
||||
if (track_descs.empty()) {
|
||||
// Be compatible with the Chrome M96, still check the AV1X encoding name
|
||||
// @see https://bugs.chromium.org/p/webrtc/issues/detail?id=13166
|
||||
track_descs = source->get_track_desc("video", "AV1X");
|
||||
}
|
||||
} else if (remote_media_desc.is_video()) {
|
||||
// TODO: check opus format specific param
|
||||
vector<SrsMediaPayloadType> payloads = remote_media_desc.find_media_with_encoding_name("H264");
|
||||
|
|
|
@ -295,11 +295,11 @@ void SrsRtcServer::set_handler(ISrsRtcServerHandler* h)
|
|||
void SrsRtcServer::set_hijacker(ISrsRtcServerHijacker* h)
|
||||
{
|
||||
hijacker = h;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcServer::exec_async_work(ISrsAsyncCallTask * t)
|
||||
{
|
||||
return async->execute(t);
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcServer::exec_async_work(ISrsAsyncCallTask * t)
|
||||
{
|
||||
return async->execute(t);
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcServer::listen_udp()
|
||||
|
@ -698,7 +698,7 @@ srs_error_t RtcServerAdapter::initialize()
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t RtcServerAdapter::run()
|
||||
srs_error_t RtcServerAdapter::run(SrsWaitGroup* wg)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ class SrsRequest;
|
|||
class SrsSdp;
|
||||
class SrsRtcSource;
|
||||
class SrsResourceManager;
|
||||
class SrsWaitGroup;
|
||||
|
||||
// The UDP black hole, for developer to use wireshark to catch plaintext packets.
|
||||
// For example, server receive UDP packets at udp://8000, and forward the plaintext packet to black hole,
|
||||
|
@ -137,7 +138,7 @@ public:
|
|||
virtual ~RtcServerAdapter();
|
||||
public:
|
||||
virtual srs_error_t initialize();
|
||||
virtual srs_error_t run();
|
||||
virtual srs_error_t run(SrsWaitGroup* wg);
|
||||
virtual void stop();
|
||||
};
|
||||
|
||||
|
|
|
@ -2516,8 +2516,6 @@ srs_error_t SrsRtcVideoRecvTrack::on_rtp(SrsRtcSource* source, SrsRtpPacket* pkt
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
pkt->frame_type = SrsFrameTypeVideo;
|
||||
|
||||
pkt->set_avsync_time(cal_avsync_time(pkt->header.get_timestamp()));
|
||||
|
||||
if ((err = source->on_rtp(pkt)) != srs_success) {
|
||||
|
|
|
@ -242,6 +242,8 @@ SrsSignalManager::SrsSignalManager(SrsServer* s)
|
|||
|
||||
SrsSignalManager::~SrsSignalManager()
|
||||
{
|
||||
srs_freep(trd);
|
||||
|
||||
srs_close_stfd(signal_read_stfd);
|
||||
|
||||
if (sig_pipe[0] > 0) {
|
||||
|
@ -250,8 +252,6 @@ SrsSignalManager::~SrsSignalManager()
|
|||
if (sig_pipe[1] > 0) {
|
||||
::close(sig_pipe[1]);
|
||||
}
|
||||
|
||||
srs_freep(trd);
|
||||
}
|
||||
|
||||
srs_error_t SrsSignalManager::initialize()
|
||||
|
@ -528,6 +528,7 @@ SrsServer::SrsServer()
|
|||
ingester = new SrsIngester();
|
||||
trd_ = new SrsSTCoroutine("srs", this, _srs_context->get_id());
|
||||
timer_ = NULL;
|
||||
wg_ = NULL;
|
||||
}
|
||||
|
||||
SrsServer::~SrsServer()
|
||||
|
@ -900,7 +901,7 @@ srs_error_t SrsServer::ingest()
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsServer::start()
|
||||
srs_error_t SrsServer::start(SrsWaitGroup* wg)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
@ -916,31 +917,25 @@ srs_error_t SrsServer::start()
|
|||
return srs_error_wrap(err, "tick");
|
||||
}
|
||||
|
||||
// OK, we start SRS server.
|
||||
wg_ = wg;
|
||||
wg->add(1);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsServer::cycle()
|
||||
void SrsServer::stop()
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// Start the inotify auto reload by watching config file.
|
||||
SrsInotifyWorker inotify(this);
|
||||
if ((err = inotify.start()) != srs_success) {
|
||||
return srs_error_wrap(err, "start inotify");
|
||||
}
|
||||
|
||||
// Do server main cycle.
|
||||
err = do_cycle();
|
||||
|
||||
#ifdef SRS_GPERF_MC
|
||||
destroy();
|
||||
|
||||
dispose();
|
||||
|
||||
// remark, for gmc, never invoke the exit().
|
||||
srs_warn("sleep a long time for system st-threads to cleanup.");
|
||||
srs_usleep(3 * 1000 * 1000);
|
||||
srs_warn("system quit");
|
||||
|
||||
return err;
|
||||
// For GCM, cleanup done.
|
||||
return;
|
||||
#endif
|
||||
|
||||
// quit normally.
|
||||
|
@ -959,12 +954,27 @@ srs_error_t SrsServer::cycle()
|
|||
}
|
||||
|
||||
srs_trace("srs terminated");
|
||||
|
||||
|
||||
// for valgrind to detect.
|
||||
srs_freep(_srs_config);
|
||||
srs_freep(_srs_log);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
srs_error_t SrsServer::cycle()
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// Start the inotify auto reload by watching config file.
|
||||
SrsInotifyWorker inotify(this);
|
||||
if ((err = inotify.start()) != srs_success) {
|
||||
return srs_error_wrap(err, "start inotify");
|
||||
}
|
||||
|
||||
// Do server main cycle.
|
||||
err = do_cycle();
|
||||
|
||||
// OK, SRS server is done.
|
||||
wg_->done();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -1616,7 +1626,7 @@ srs_error_t SrsServerAdapter::initialize()
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsServerAdapter::run()
|
||||
srs_error_t SrsServerAdapter::run(SrsWaitGroup* wg)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
@ -1653,7 +1663,7 @@ srs_error_t SrsServerAdapter::run()
|
|||
return srs_error_wrap(err, "ingest");
|
||||
}
|
||||
|
||||
if ((err = srs->start()) != srs_success) {
|
||||
if ((err = srs->start(wg)) != srs_success) {
|
||||
return srs_error_wrap(err, "start");
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ class SrsTcpListener;
|
|||
class SrsAppCasterFlv;
|
||||
class SrsResourceManager;
|
||||
class SrsLatestVersion;
|
||||
class SrsWaitGroup;
|
||||
|
||||
// The listener type for server to identify the connection,
|
||||
// that is, use different type to process the connection.
|
||||
|
@ -205,6 +206,7 @@ private:
|
|||
SrsResourceManager* conn_manager;
|
||||
SrsCoroutine* trd_;
|
||||
SrsHourGlass* timer_;
|
||||
SrsWaitGroup* wg_;
|
||||
private:
|
||||
// The pid file fd, lock the file write when server is running.
|
||||
// @remark the init.d script should cleanup the pid file, when stop service,
|
||||
|
@ -253,7 +255,9 @@ public:
|
|||
virtual srs_error_t register_signal();
|
||||
virtual srs_error_t http_handle();
|
||||
virtual srs_error_t ingest();
|
||||
virtual srs_error_t start();
|
||||
public:
|
||||
virtual srs_error_t start(SrsWaitGroup* wg);
|
||||
void stop();
|
||||
// interface ISrsCoroutineHandler
|
||||
public:
|
||||
virtual srs_error_t cycle();
|
||||
|
@ -339,7 +343,7 @@ public:
|
|||
virtual ~SrsServerAdapter();
|
||||
public:
|
||||
virtual srs_error_t initialize();
|
||||
virtual srs_error_t run();
|
||||
virtual srs_error_t run(SrsWaitGroup* wg);
|
||||
virtual void stop();
|
||||
public:
|
||||
virtual SrsServer* instance();
|
||||
|
|
|
@ -297,3 +297,35 @@ void* SrsFastCoroutine::pfn(void* arg)
|
|||
return (void*)err;
|
||||
}
|
||||
|
||||
SrsWaitGroup::SrsWaitGroup()
|
||||
{
|
||||
nn_ = 0;
|
||||
done_ = srs_cond_new();
|
||||
}
|
||||
|
||||
SrsWaitGroup::~SrsWaitGroup()
|
||||
{
|
||||
wait();
|
||||
srs_cond_destroy(done_);
|
||||
}
|
||||
|
||||
void SrsWaitGroup::add(int n)
|
||||
{
|
||||
nn_ += n;
|
||||
}
|
||||
|
||||
void SrsWaitGroup::done()
|
||||
{
|
||||
nn_--;
|
||||
if (nn_ <= 0) {
|
||||
srs_cond_signal(done_);
|
||||
}
|
||||
}
|
||||
|
||||
void SrsWaitGroup::wait()
|
||||
{
|
||||
if (nn_ > 0) {
|
||||
srs_cond_wait(done_);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -189,5 +189,23 @@ private:
|
|||
static void* pfn(void* arg);
|
||||
};
|
||||
|
||||
// Like goroytine sync.WaitGroup.
|
||||
class SrsWaitGroup
|
||||
{
|
||||
private:
|
||||
int nn_;
|
||||
srs_cond_t done_;
|
||||
public:
|
||||
SrsWaitGroup();
|
||||
virtual ~SrsWaitGroup();
|
||||
public:
|
||||
// When start for n coroutines.
|
||||
void add(int n);
|
||||
// When coroutine is done.
|
||||
void done();
|
||||
// Wait for all corotine to be done.
|
||||
void wait();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#define RTMP_SIG_SRS_DOMAIN "ossrs.net"
|
||||
|
||||
// The current stable release.
|
||||
#define VERSION_STABLE 3
|
||||
#define VERSION_STABLE 4
|
||||
#define VERSION_STABLE_BRANCH SRS_XSTR(VERSION_STABLE) ".0release"
|
||||
|
||||
// For 32bit os, 2G big file limit for unistd io,
|
||||
|
|
|
@ -9,50 +9,62 @@
|
|||
|
||||
#include <srs_core.hpp>
|
||||
|
||||
/**
|
||||
* To free the instance in the current scope, for instance, MyClass* ptr,
|
||||
* which is a ptr and this class will:
|
||||
* 1. free the ptr.
|
||||
* 2. set ptr to NULL.
|
||||
*
|
||||
* Usage:
|
||||
* MyClass* po = new MyClass();
|
||||
* // ...... use po
|
||||
* SrsAutoFree(MyClass, po);
|
||||
*
|
||||
* Usage for array:
|
||||
* MyClass** pa = new MyClass*[size];
|
||||
* // ....... use pa
|
||||
* SrsAutoFreeA(MyClass*, pa);
|
||||
*
|
||||
* @remark the MyClass can be basic type, for instance, SrsAutoFreeA(char, pstr),
|
||||
* where the char* pstr = new char[size].
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
|
||||
// To free the instance in the current scope, for instance, MyClass* ptr,
|
||||
// which is a ptr and this class will:
|
||||
// 1. free the ptr.
|
||||
// 2. set ptr to NULL.
|
||||
//
|
||||
// Usage:
|
||||
// MyClass* po = new MyClass();
|
||||
// // ...... use po
|
||||
// SrsAutoFree(MyClass, po);
|
||||
//
|
||||
// Usage for array:
|
||||
// MyClass** pa = new MyClass*[size];
|
||||
// // ....... use pa
|
||||
// SrsAutoFreeA(MyClass*, pa);
|
||||
//
|
||||
// @remark the MyClass can be basic type, for instance, SrsAutoFreeA(char, pstr),
|
||||
// where the char* pstr = new char[size].
|
||||
// To delete object.
|
||||
#define SrsAutoFree(className, instance) \
|
||||
impl_SrsAutoFree<className> _auto_free_##instance(&instance, false)
|
||||
impl_SrsAutoFree<className> _auto_free_##instance(&instance, false, false)
|
||||
// To delete array.
|
||||
#define SrsAutoFreeA(className, instance) \
|
||||
impl_SrsAutoFree<className> _auto_free_array_##instance(&instance, true)
|
||||
impl_SrsAutoFree<className> _auto_free_array_##instance(&instance, true, false)
|
||||
// Use free instead of delete.
|
||||
#define SrsAutoFreeF(className, instance) \
|
||||
impl_SrsAutoFree<className> _auto_free_##instance(&instance, false, true)
|
||||
// The template implementation.
|
||||
template<class T>
|
||||
class impl_SrsAutoFree
|
||||
{
|
||||
private:
|
||||
T** ptr;
|
||||
bool is_array;
|
||||
bool _use_free;
|
||||
public:
|
||||
impl_SrsAutoFree(T** p, bool array) {
|
||||
impl_SrsAutoFree(T** p, bool array, bool use_free) {
|
||||
ptr = p;
|
||||
is_array = array;
|
||||
_use_free = use_free;
|
||||
}
|
||||
|
||||
virtual ~impl_SrsAutoFree() {
|
||||
if (ptr == NULL || *ptr == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_array) {
|
||||
delete[] *ptr;
|
||||
|
||||
if (_use_free) {
|
||||
free(*ptr);
|
||||
} else {
|
||||
delete *ptr;
|
||||
if (is_array) {
|
||||
delete[] *ptr;
|
||||
} else {
|
||||
delete *ptr;
|
||||
}
|
||||
}
|
||||
|
||||
*ptr = NULL;
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
|
||||
#define VERSION_MAJOR 4
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 205
|
||||
#define VERSION_REVISION 212
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,6 +19,11 @@
|
|||
#include <iomanip>
|
||||
using namespace std;
|
||||
|
||||
// For CentOS 6 or C++98, @see https://github.com/ossrs/srs/issues/2815
|
||||
#ifndef UINT32_MAX
|
||||
#define UINT32_MAX (4294967295U)
|
||||
#endif
|
||||
|
||||
#define SRS_MP4_EOF_SIZE 0
|
||||
#define SRS_MP4_USE_LARGE_SIZE 1
|
||||
|
||||
|
@ -2863,6 +2868,18 @@ void SrsMp4SampleTableBox::set_stco(SrsMp4ChunkOffsetBox* v)
|
|||
boxes.push_back(v);
|
||||
}
|
||||
|
||||
SrsMp4ChunkLargeOffsetBox* SrsMp4SampleTableBox::co64()
|
||||
{
|
||||
SrsMp4Box* box = get(SrsMp4BoxTypeCO64);
|
||||
return dynamic_cast<SrsMp4ChunkLargeOffsetBox*>(box);
|
||||
}
|
||||
|
||||
void SrsMp4SampleTableBox::set_co64(SrsMp4ChunkLargeOffsetBox* v)
|
||||
{
|
||||
remove(SrsMp4BoxTypeCO64);
|
||||
boxes.push_back(v);
|
||||
}
|
||||
|
||||
SrsMp4SampleSizeBox* SrsMp4SampleTableBox::stsz()
|
||||
{
|
||||
SrsMp4Box* box = get(SrsMp4BoxTypeSTSZ);
|
||||
|
@ -4845,10 +4862,19 @@ srs_error_t SrsMp4SampleManager::write(SrsMp4MovieBox* moov)
|
|||
SrsMp4SampleSizeBox* stsz = new SrsMp4SampleSizeBox();
|
||||
stbl->set_stsz(stsz);
|
||||
|
||||
SrsMp4ChunkOffsetBox* stco = new SrsMp4ChunkOffsetBox();
|
||||
stbl->set_stco(stco);
|
||||
SrsMp4FullBox* co = NULL;
|
||||
// When sample offset less than UINT32_MAX, we use stco(support 32bit offset) box to save storage space.
|
||||
if (samples.empty() || (*samples.rbegin())->offset < UINT32_MAX) {
|
||||
// stco support 32bit offset.
|
||||
co = new SrsMp4ChunkOffsetBox();
|
||||
stbl->set_stco(static_cast<SrsMp4ChunkOffsetBox*>(co));
|
||||
} else {
|
||||
// When sample offset bigger than UINT32_MAX, we use co64(support 64bit offset) box to avoid overflow.
|
||||
co = new SrsMp4ChunkLargeOffsetBox();
|
||||
stbl->set_co64(static_cast<SrsMp4ChunkLargeOffsetBox*>(co));
|
||||
}
|
||||
|
||||
if ((err = write_track(SrsFrameTypeVideo, stts, stss, ctts, stsc, stsz, stco)) != srs_success) {
|
||||
if ((err = write_track(SrsFrameTypeVideo, stts, stss, ctts, stsc, stsz, co)) != srs_success) {
|
||||
return srs_error_wrap(err, "write vide track");
|
||||
}
|
||||
}
|
||||
|
@ -4869,10 +4895,16 @@ srs_error_t SrsMp4SampleManager::write(SrsMp4MovieBox* moov)
|
|||
SrsMp4SampleSizeBox* stsz = new SrsMp4SampleSizeBox();
|
||||
stbl->set_stsz(stsz);
|
||||
|
||||
SrsMp4ChunkOffsetBox* stco = new SrsMp4ChunkOffsetBox();
|
||||
stbl->set_stco(stco);
|
||||
SrsMp4FullBox* co = NULL;
|
||||
if (samples.empty() || (*samples.rbegin())->offset < UINT32_MAX) {
|
||||
co = new SrsMp4ChunkOffsetBox();
|
||||
stbl->set_stco(static_cast<SrsMp4ChunkOffsetBox*>(co));
|
||||
} else {
|
||||
co = new SrsMp4ChunkLargeOffsetBox();
|
||||
stbl->set_co64(static_cast<SrsMp4ChunkLargeOffsetBox*>(co));
|
||||
}
|
||||
|
||||
if ((err = write_track(SrsFrameTypeAudio, stts, stss, ctts, stsc, stsz, stco)) != srs_success) {
|
||||
if ((err = write_track(SrsFrameTypeAudio, stts, stss, ctts, stsc, stsz, co)) != srs_success) {
|
||||
return srs_error_wrap(err, "write soun track");
|
||||
}
|
||||
}
|
||||
|
@ -4924,7 +4956,7 @@ srs_error_t SrsMp4SampleManager::write(SrsMp4MovieFragmentBox* moof, uint64_t& d
|
|||
|
||||
srs_error_t SrsMp4SampleManager::write_track(SrsFrameType track,
|
||||
SrsMp4DecodingTime2SampleBox* stts, SrsMp4SyncSampleBox* stss, SrsMp4CompositionTime2SampleBox* ctts,
|
||||
SrsMp4Sample2ChunkBox* stsc, SrsMp4SampleSizeBox* stsz, SrsMp4ChunkOffsetBox* stco)
|
||||
SrsMp4Sample2ChunkBox* stsc, SrsMp4SampleSizeBox* stsz, SrsMp4FullBox* co)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
@ -4935,7 +4967,7 @@ srs_error_t SrsMp4SampleManager::write_track(SrsFrameType track,
|
|||
vector<SrsMp4CttsEntry> ctts_entries;
|
||||
|
||||
vector<uint32_t> stsz_entries;
|
||||
vector<uint32_t> stco_entries;
|
||||
vector<uint64_t> co_entries;
|
||||
vector<uint32_t> stss_entries;
|
||||
|
||||
SrsMp4Sample* previous = NULL;
|
||||
|
@ -4947,7 +4979,7 @@ srs_error_t SrsMp4SampleManager::write_track(SrsFrameType track,
|
|||
}
|
||||
|
||||
stsz_entries.push_back(sample->nb_data);
|
||||
stco_entries.push_back((uint32_t)sample->offset);
|
||||
co_entries.push_back((uint64_t)sample->offset);
|
||||
|
||||
if (sample->frame_type == SrsVideoAvcFrameTypeKeyFrame) {
|
||||
stss_entries.push_back(sample->index + 1);
|
||||
|
@ -5020,11 +5052,22 @@ srs_error_t SrsMp4SampleManager::write_track(SrsFrameType track,
|
|||
}
|
||||
}
|
||||
|
||||
if (stco && !stco_entries.empty()) {
|
||||
stco->entry_count = (uint32_t)stco_entries.size();
|
||||
stco->entries = new uint32_t[stco->entry_count];
|
||||
for (int i = 0; i < (int)stco->entry_count; i++) {
|
||||
stco->entries[i] = stco_entries.at(i);
|
||||
if (!co_entries.empty()) {
|
||||
SrsMp4ChunkOffsetBox* stco = dynamic_cast<SrsMp4ChunkOffsetBox*>(co);
|
||||
SrsMp4ChunkLargeOffsetBox* co64 = dynamic_cast<SrsMp4ChunkLargeOffsetBox*>(co);
|
||||
|
||||
if (stco) {
|
||||
stco->entry_count = (uint32_t)co_entries.size();
|
||||
stco->entries = new uint32_t[stco->entry_count];
|
||||
for (int i = 0; i < (int)stco->entry_count; i++) {
|
||||
stco->entries[i] = co_entries.at(i);
|
||||
}
|
||||
} else if (co64) {
|
||||
co64->entry_count = (uint32_t)co_entries.size();
|
||||
co64->entries = new uint64_t[co64->entry_count];
|
||||
for (int i = 0; i < (int)co64->entry_count; i++) {
|
||||
co64->entries[i] = co_entries.at(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6181,6 +6224,7 @@ srs_error_t SrsMp4M2tsInitEncoder::write(SrsFormat* format, bool video, int tid)
|
|||
SrsMp4SampleSizeBox* stsz = new SrsMp4SampleSizeBox();
|
||||
stbl->set_stsz(stsz);
|
||||
|
||||
// TODO: FIXME: need to check using stco or co64?
|
||||
SrsMp4ChunkOffsetBox* stco = new SrsMp4ChunkOffsetBox();
|
||||
stbl->set_stco(stco);
|
||||
|
||||
|
@ -6281,6 +6325,7 @@ srs_error_t SrsMp4M2tsInitEncoder::write(SrsFormat* format, bool video, int tid)
|
|||
SrsMp4SampleSizeBox* stsz = new SrsMp4SampleSizeBox();
|
||||
stbl->set_stsz(stsz);
|
||||
|
||||
// TODO: FIXME: need to check using stco or co64?
|
||||
SrsMp4ChunkOffsetBox* stco = new SrsMp4ChunkOffsetBox();
|
||||
stbl->set_stco(stco);
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ class SrsMp4AvccBox;
|
|||
class SrsMp4AudioSampleEntry;
|
||||
class SrsMp4EsdsBox;
|
||||
class SrsMp4ChunkOffsetBox;
|
||||
class SrsMp4ChunkLargeOffsetBox;
|
||||
class SrsMp4SampleSizeBox;
|
||||
class SrsMp4Sample2ChunkBox;
|
||||
class SrsMp4DecodingTime2SampleBox;
|
||||
|
@ -1188,6 +1189,9 @@ public:
|
|||
// Get the chunk offset box.
|
||||
virtual SrsMp4ChunkOffsetBox* stco();
|
||||
virtual void set_stco(SrsMp4ChunkOffsetBox* v);
|
||||
// Get the chunk large offset box.
|
||||
virtual SrsMp4ChunkLargeOffsetBox* co64();
|
||||
virtual void set_co64(SrsMp4ChunkLargeOffsetBox* v);
|
||||
// Get the sample size box.
|
||||
virtual SrsMp4SampleSizeBox* stsz();
|
||||
virtual void set_stsz(SrsMp4SampleSizeBox* v);
|
||||
|
@ -1906,7 +1910,7 @@ public:
|
|||
private:
|
||||
virtual srs_error_t write_track(SrsFrameType track,
|
||||
SrsMp4DecodingTime2SampleBox* stts, SrsMp4SyncSampleBox* stss, SrsMp4CompositionTime2SampleBox* ctts,
|
||||
SrsMp4Sample2ChunkBox* stsc, SrsMp4SampleSizeBox* stsz, SrsMp4ChunkOffsetBox* stco);
|
||||
SrsMp4Sample2ChunkBox* stsc, SrsMp4SampleSizeBox* stsz, SrsMp4FullBox* co);
|
||||
virtual srs_error_t do_load(std::map<uint64_t, SrsMp4Sample*>& tses, SrsMp4MovieBox* moov);
|
||||
private:
|
||||
// Load the samples of track from stco, stsz and stsc.
|
||||
|
|
|
@ -456,8 +456,8 @@ srs_error_t SrsHttpFileServer::serve_file(ISrsHttpResponseWriter* w, ISrsHttpMes
|
|||
|
||||
// write body.
|
||||
int64_t left = length;
|
||||
if ((err = copy(w, fs, r, (int)left)) != srs_success) {
|
||||
return srs_error_wrap(err, "copy file=%s size=%d", fullpath.c_str(), (int)left);
|
||||
if ((err = copy(w, fs, r, left)) != srs_success) {
|
||||
return srs_error_wrap(err, "copy file=%s size=%" PRId64, fullpath.c_str(), left);
|
||||
}
|
||||
|
||||
if ((err = w->final_request()) != srs_success) {
|
||||
|
@ -474,7 +474,7 @@ srs_error_t SrsHttpFileServer::serve_flv_file(ISrsHttpResponseWriter* w, ISrsHtt
|
|||
return serve_file(w, r, fullpath);
|
||||
}
|
||||
|
||||
int offset = ::atoi(start.c_str());
|
||||
int64_t offset = ::atoll(start.c_str());
|
||||
if (offset <= 0) {
|
||||
return serve_file(w, r, fullpath);
|
||||
}
|
||||
|
@ -507,15 +507,15 @@ srs_error_t SrsHttpFileServer::serve_mp4_file(ISrsHttpResponseWriter* w, ISrsHtt
|
|||
}
|
||||
|
||||
// parse the start in query string
|
||||
int start = 0;
|
||||
int64_t start = 0;
|
||||
if (pos > 0) {
|
||||
start = ::atoi(range.substr(0, pos).c_str());
|
||||
start = ::atoll(range.substr(0, pos).c_str());
|
||||
}
|
||||
|
||||
// parse end in query string.
|
||||
int end = -1;
|
||||
int64_t end = -1;
|
||||
if (pos < range.length() - 1) {
|
||||
end = ::atoi(range.substr(pos + 1).c_str());
|
||||
end = ::atoll(range.substr(pos + 1).c_str());
|
||||
}
|
||||
|
||||
// invalid param, serve as whole mp4 file.
|
||||
|
@ -524,39 +524,39 @@ srs_error_t SrsHttpFileServer::serve_mp4_file(ISrsHttpResponseWriter* w, ISrsHtt
|
|||
}
|
||||
|
||||
return serve_mp4_stream(w, r, fullpath, start, end);
|
||||
}
|
||||
|
||||
srs_error_t SrsHttpFileServer::serve_m3u8_file(ISrsHttpResponseWriter * w, ISrsHttpMessage * r, std::string fullpath)
|
||||
{
|
||||
return serve_m3u8_ctx(w, r, fullpath);
|
||||
}
|
||||
|
||||
srs_error_t SrsHttpFileServer::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int offset)
|
||||
srs_error_t SrsHttpFileServer::serve_m3u8_file(ISrsHttpResponseWriter * w, ISrsHttpMessage * r, std::string fullpath)
|
||||
{
|
||||
return serve_m3u8_ctx(w, r, fullpath);
|
||||
}
|
||||
|
||||
srs_error_t SrsHttpFileServer::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int64_t offset)
|
||||
{
|
||||
// @remark For common http file server, we don't support stream request, please use SrsVodStream instead.
|
||||
// TODO: FIXME: Support range in header https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Range_requests
|
||||
return serve_file(w, r, fullpath);
|
||||
}
|
||||
|
||||
srs_error_t SrsHttpFileServer::serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int start, int end)
|
||||
srs_error_t SrsHttpFileServer::serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int64_t start, int64_t end)
|
||||
{
|
||||
// @remark For common http file server, we don't support stream request, please use SrsVodStream instead.
|
||||
// TODO: FIXME: Support range in header https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Range_requests
|
||||
return serve_file(w, r, fullpath);
|
||||
}
|
||||
|
||||
srs_error_t SrsHttpFileServer::serve_m3u8_ctx(ISrsHttpResponseWriter * w, ISrsHttpMessage * r, std::string fullpath)
|
||||
{
|
||||
// @remark For common http file server, we don't support stream request, please use SrsVodStream instead.
|
||||
// TODO: FIXME: Support range in header https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Range_requests
|
||||
return serve_file(w, r, fullpath);
|
||||
}
|
||||
|
||||
srs_error_t SrsHttpFileServer::copy(ISrsHttpResponseWriter* w, SrsFileReader* fs, ISrsHttpMessage* r, int size)
|
||||
srs_error_t SrsHttpFileServer::serve_m3u8_ctx(ISrsHttpResponseWriter * w, ISrsHttpMessage * r, std::string fullpath)
|
||||
{
|
||||
// @remark For common http file server, we don't support stream request, please use SrsVodStream instead.
|
||||
// TODO: FIXME: Support range in header https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Range_requests
|
||||
return serve_file(w, r, fullpath);
|
||||
}
|
||||
|
||||
srs_error_t SrsHttpFileServer::copy(ISrsHttpResponseWriter* w, SrsFileReader* fs, ISrsHttpMessage* r, int64_t size)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
int left = size;
|
||||
int64_t left = size;
|
||||
char* buf = new char[SRS_HTTP_TS_SEND_BUFFER_SIZE];
|
||||
SrsAutoFreeA(char, buf);
|
||||
|
||||
|
@ -564,12 +564,12 @@ srs_error_t SrsHttpFileServer::copy(ISrsHttpResponseWriter* w, SrsFileReader* fs
|
|||
ssize_t nread = -1;
|
||||
int max_read = srs_min(left, SRS_HTTP_TS_SEND_BUFFER_SIZE);
|
||||
if ((err = fs->read(buf, max_read, &nread)) != srs_success) {
|
||||
return srs_error_wrap(err, "read limit=%d, left=%d", max_read, left);
|
||||
return srs_error_wrap(err, "read limit=%d, left=%" PRId64, max_read, left);
|
||||
}
|
||||
|
||||
left -= nread;
|
||||
if ((err = w->write(buf, (int)nread)) != srs_success) {
|
||||
return srs_error_wrap(err, "write limit=%d, bytes=%d, left=%d", max_read, (int)nread, left);
|
||||
return srs_error_wrap(err, "write limit=%d, bytes=%d, left=%" PRId64, max_read, (int)nread, left);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -288,12 +288,12 @@ private:
|
|||
virtual srs_error_t serve_m3u8_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath);
|
||||
protected:
|
||||
// When access flv file with x.flv?start=xxx
|
||||
virtual srs_error_t serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int offset);
|
||||
virtual srs_error_t serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int64_t offset);
|
||||
// When access mp4 file with x.mp4?range=start-end
|
||||
// @param start the start offset in bytes.
|
||||
// @param end the end offset in bytes. -1 to end of file.
|
||||
// @remark response data in [start, end].
|
||||
virtual srs_error_t serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int start, int end);
|
||||
virtual srs_error_t serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int64_t start, int64_t end);
|
||||
// For HLS protocol.
|
||||
// When the request url, like as "http://127.0.0.1:8080/live/livestream.m3u8",
|
||||
// returns the response like as "http://127.0.0.1:8080/live/livestream.m3u8?hls_ctx=12345678" .
|
||||
|
@ -306,7 +306,7 @@ protected:
|
|||
virtual srs_error_t serve_m3u8_ctx(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath);
|
||||
protected:
|
||||
// Copy the fs to response writer in size bytes.
|
||||
virtual srs_error_t copy(ISrsHttpResponseWriter* w, SrsFileReader* fs, ISrsHttpMessage* r, int size);
|
||||
virtual srs_error_t copy(ISrsHttpResponseWriter* w, SrsFileReader* fs, ISrsHttpMessage* r, int64_t size);
|
||||
};
|
||||
|
||||
// The mux entry for server mux.
|
||||
|
|
|
@ -758,7 +758,7 @@ srs_error_t SrsHttpResponseWriter::write(char* data, int size)
|
|||
// check the bytes send and content length.
|
||||
written += size;
|
||||
if (content_length != -1 && written > content_length) {
|
||||
return srs_error_new(ERROR_HTTP_CONTENT_LENGTH, "overflow writen=%d, max=%d", (int)written, (int)content_length);
|
||||
return srs_error_new(ERROR_HTTP_CONTENT_LENGTH, "overflow writen=%" PRId64 ", max=%" PRId64, written, content_length);
|
||||
}
|
||||
|
||||
// ignore NULL content.
|
||||
|
|
|
@ -248,7 +248,7 @@ srs_error_t srs_tcp_listen(std::string ip, int port, srs_netfd_t* pfd)
|
|||
hints.ai_flags = AI_NUMERICHOST;
|
||||
|
||||
addrinfo* r = NULL;
|
||||
SrsAutoFree(addrinfo, r);
|
||||
SrsAutoFreeF(addrinfo, r);
|
||||
if(getaddrinfo(ip.c_str(), sport, (const addrinfo*)&hints, &r)) {
|
||||
return srs_error_new(ERROR_SYSTEM_IP_INVALID, "getaddrinfo hints=(%d,%d,%d)",
|
||||
hints.ai_family, hints.ai_socktype, hints.ai_flags);
|
||||
|
|
|
@ -323,7 +323,7 @@ srs_error_t SrtServerAdapter::initialize()
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrtServerAdapter::run()
|
||||
srs_error_t SrtServerAdapter::run(SrsWaitGroup* wg)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <srs_app_hybrid.hpp>
|
||||
|
||||
class srt_handle;
|
||||
class SrsWaitGroup;
|
||||
|
||||
class srt_server {
|
||||
public:
|
||||
|
@ -59,7 +60,7 @@ public:
|
|||
virtual ~SrtServerAdapter();
|
||||
public:
|
||||
virtual srs_error_t initialize();
|
||||
virtual srs_error_t run();
|
||||
virtual srs_error_t run(SrsWaitGroup* wg);
|
||||
virtual void stop();
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue