Refine source lock to fix race condition in source managers. v7.0.61 (#4449)
This PR fixes a critical race condition in SRS source managers where multiple coroutines could create duplicate sources for the same stream. - **Atomic source creation**: Source lookup, creation, and pool insertion now happen atomically within lock scope - **Consistent interface**: Standardize on `ISrsRequest*` interface throughout codebase - **Handler simplification**: Remove `ISrsLiveSourceHandler*` parameter, obtain from global server instance --------- Co-authored-by: OSSRS-AI <winlinam@gmail.com>
This commit is contained in:
parent
6ec97067de
commit
1b6f97bd2d
2
trunk/configure
vendored
2
trunk/configure
vendored
|
|
@ -439,7 +439,7 @@ if [[ $SRS_UTEST == YES ]]; then
|
|||
"srs_utest_config" "srs_utest_rtmp" "srs_utest_http" "srs_utest_avc" "srs_utest_reload"
|
||||
"srs_utest_mp4" "srs_utest_service" "srs_utest_app" "srs_utest_rtc" "srs_utest_config2"
|
||||
"srs_utest_protocol" "srs_utest_protocol2" "srs_utest_kernel2" "srs_utest_protocol3"
|
||||
"srs_utest_st" "srs_utest_rtc2" "srs_utest_rtc3" "srs_utest_fmp4")
|
||||
"srs_utest_st" "srs_utest_rtc2" "srs_utest_rtc3" "srs_utest_fmp4" "srs_utest_source_lock")
|
||||
if [[ $SRS_SRT == YES ]]; then
|
||||
MODULE_FILES+=("srs_utest_srt")
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ The changelog for SRS.
|
|||
<a name="v7-changes"></a>
|
||||
|
||||
## SRS 7.0 Changelog
|
||||
* v7.0, 2025-08-22, Merge [#4449](https://github.com/ossrs/srs/pull/4449): Refine source lock. v7.0.61 (#4449)
|
||||
* v7.0, 2025-08-21, Merge [#4447](https://github.com/ossrs/srs/pull/4447): AI: Always enable WebRTC and enforce C++98 compatibility. v7.0.60 (#4447)
|
||||
* v7.0, 2025-08-20, Merge [#4445](https://github.com/ossrs/srs/pull/4445): AI: Remove multi-threading support and change to single-thread architecture. v7.0.59 (#4445)
|
||||
* v7.0, 2025-08-19, Merge [#4444](https://github.com/ossrs/srs/pull/4444): AI: Refine hooks from static to instance functions. v7.0.58 (#4444)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ class SrsConfDirective;
|
|||
class SrsHttpServeMux;
|
||||
class SrsRtmpClient;
|
||||
class SrsStSocket;
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsPithyPrint;
|
||||
class ISrsHttpResponseReader;
|
||||
class SrsFlvDecoder;
|
||||
|
|
|
|||
|
|
@ -342,7 +342,7 @@ bool srs_stream_caster_is_gb28181(string caster)
|
|||
return caster == "gb28181";
|
||||
}
|
||||
|
||||
bool srs_config_apply_filter(SrsConfDirective *dvr_apply, SrsRequest *req)
|
||||
bool srs_config_apply_filter(SrsConfDirective *dvr_apply, ISrsRequest *req)
|
||||
{
|
||||
static bool DEFAULT = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -19,14 +19,13 @@
|
|||
#include <srs_app_reload.hpp>
|
||||
#include <srs_app_st.hpp>
|
||||
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsFileWriter;
|
||||
class SrsJsonObject;
|
||||
class SrsJsonArray;
|
||||
class SrsJsonAny;
|
||||
|
||||
class SrsConfig;
|
||||
class SrsRequest;
|
||||
class SrsJsonArray;
|
||||
class SrsConfDirective;
|
||||
|
||||
|
|
@ -106,7 +105,7 @@ extern bool srs_stream_caster_is_udp(std::string caster);
|
|||
extern bool srs_stream_caster_is_flv(std::string caster);
|
||||
extern bool srs_stream_caster_is_gb28181(std::string caster);
|
||||
// Whether the dvr_apply active the stream specified by req.
|
||||
extern bool srs_config_apply_filter(SrsConfDirective *dvr_apply, SrsRequest *req);
|
||||
extern bool srs_config_apply_filter(SrsConfDirective *dvr_apply, ISrsRequest *req);
|
||||
|
||||
// Convert bool in str to on/off
|
||||
extern std::string srs_config_bool2switch(std::string sbool);
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@ SrsCoWorkers::SrsCoWorkers()
|
|||
|
||||
SrsCoWorkers::~SrsCoWorkers()
|
||||
{
|
||||
map<string, SrsRequest *>::iterator it;
|
||||
map<string, ISrsRequest *>::iterator it;
|
||||
for (it = streams.begin(); it != streams.end(); ++it) {
|
||||
SrsRequest *r = it->second;
|
||||
ISrsRequest *r = it->second;
|
||||
srs_freep(r);
|
||||
}
|
||||
streams.clear();
|
||||
|
|
@ -42,7 +42,7 @@ SrsCoWorkers *SrsCoWorkers::instance()
|
|||
|
||||
SrsJsonAny *SrsCoWorkers::dumps(string vhost, string coworker, string app, string stream)
|
||||
{
|
||||
SrsRequest *r = find_stream_info(vhost, app, stream);
|
||||
ISrsRequest *r = find_stream_info(vhost, app, stream);
|
||||
if (!r) {
|
||||
// TODO: FIXME: Find stream from our origin util return to the start point.
|
||||
return SrsJsonAny::null();
|
||||
|
|
@ -103,7 +103,7 @@ SrsJsonAny *SrsCoWorkers::dumps(string vhost, string coworker, string app, strin
|
|||
->set("routers", routers);
|
||||
}
|
||||
|
||||
SrsRequest *SrsCoWorkers::find_stream_info(string vhost, string app, string stream)
|
||||
ISrsRequest *SrsCoWorkers::find_stream_info(string vhost, string app, string stream)
|
||||
{
|
||||
// First, we should parse the vhost, if not exists, try default vhost instead.
|
||||
SrsConfDirective *conf = _srs_config->get_vhost(vhost, true);
|
||||
|
|
@ -113,7 +113,7 @@ SrsRequest *SrsCoWorkers::find_stream_info(string vhost, string app, string stre
|
|||
|
||||
// Get stream information from local cache.
|
||||
string url = srs_generate_stream_url(conf->arg0(), app, stream);
|
||||
map<string, SrsRequest *>::iterator it = streams.find(url);
|
||||
map<string, ISrsRequest *>::iterator it = streams.find(url);
|
||||
if (it == streams.end()) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -121,14 +121,14 @@ SrsRequest *SrsCoWorkers::find_stream_info(string vhost, string app, string stre
|
|||
return it->second;
|
||||
}
|
||||
|
||||
srs_error_t SrsCoWorkers::on_publish(SrsRequest *r)
|
||||
srs_error_t SrsCoWorkers::on_publish(ISrsRequest *r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
string url = r->get_stream_url();
|
||||
|
||||
// Delete the previous stream informations.
|
||||
map<string, SrsRequest *>::iterator it = streams.find(url);
|
||||
map<string, ISrsRequest *>::iterator it = streams.find(url);
|
||||
if (it != streams.end()) {
|
||||
srs_freep(it->second);
|
||||
}
|
||||
|
|
@ -139,11 +139,11 @@ srs_error_t SrsCoWorkers::on_publish(SrsRequest *r)
|
|||
return err;
|
||||
}
|
||||
|
||||
void SrsCoWorkers::on_unpublish(SrsRequest *r)
|
||||
void SrsCoWorkers::on_unpublish(ISrsRequest *r)
|
||||
{
|
||||
string url = r->get_stream_url();
|
||||
|
||||
map<string, SrsRequest *>::iterator it = streams.find(url);
|
||||
map<string, ISrsRequest *>::iterator it = streams.find(url);
|
||||
if (it != streams.end()) {
|
||||
srs_freep(it->second);
|
||||
streams.erase(it);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#include <string>
|
||||
|
||||
class SrsJsonAny;
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsLiveSource;
|
||||
|
||||
// For origin cluster.
|
||||
|
|
@ -23,7 +23,7 @@ private:
|
|||
static SrsCoWorkers *_instance;
|
||||
|
||||
private:
|
||||
std::map<std::string, SrsRequest *> streams;
|
||||
std::map<std::string, ISrsRequest *> streams;
|
||||
|
||||
private:
|
||||
SrsCoWorkers();
|
||||
|
|
@ -36,11 +36,11 @@ public:
|
|||
virtual SrsJsonAny *dumps(std::string vhost, std::string coworker, std::string app, std::string stream);
|
||||
|
||||
private:
|
||||
virtual SrsRequest *find_stream_info(std::string vhost, std::string app, std::string stream);
|
||||
virtual ISrsRequest *find_stream_info(std::string vhost, std::string app, std::string stream);
|
||||
|
||||
public:
|
||||
virtual srs_error_t on_publish(SrsRequest *r);
|
||||
virtual void on_unpublish(SrsRequest *r);
|
||||
virtual srs_error_t on_publish(ISrsRequest *r);
|
||||
virtual void on_unpublish(ISrsRequest *r);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ SrsFragmentedMp4::~SrsFragmentedMp4()
|
|||
srs_freep(fw);
|
||||
}
|
||||
|
||||
srs_error_t SrsFragmentedMp4::initialize(SrsRequest *r, bool video, int64_t time, SrsMpdWriter *mpd, uint32_t tid)
|
||||
srs_error_t SrsFragmentedMp4::initialize(ISrsRequest *r, bool video, int64_t time, SrsMpdWriter *mpd, uint32_t tid)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -185,7 +185,7 @@ void SrsMpdWriter::dispose()
|
|||
}
|
||||
}
|
||||
|
||||
srs_error_t SrsMpdWriter::initialize(SrsRequest *r)
|
||||
srs_error_t SrsMpdWriter::initialize(ISrsRequest *r)
|
||||
{
|
||||
req = r;
|
||||
return srs_success;
|
||||
|
|
@ -193,7 +193,7 @@ srs_error_t SrsMpdWriter::initialize(SrsRequest *r)
|
|||
|
||||
srs_error_t SrsMpdWriter::on_publish()
|
||||
{
|
||||
SrsRequest *r = req;
|
||||
ISrsRequest *r = req;
|
||||
|
||||
fragment = _srs_config->get_dash_fragment(r->vhost);
|
||||
update_period = _srs_config->get_dash_update_period(r->vhost);
|
||||
|
|
@ -394,7 +394,7 @@ void SrsDashController::dispose()
|
|||
srs_trace("gracefully dispose dash %s", req ? req->get_stream_url().c_str() : "");
|
||||
}
|
||||
|
||||
srs_error_t SrsDashController::initialize(SrsRequest *r)
|
||||
srs_error_t SrsDashController::initialize(ISrsRequest *r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -411,7 +411,7 @@ srs_error_t SrsDashController::on_publish()
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *r = req;
|
||||
ISrsRequest *r = req;
|
||||
|
||||
fragment = _srs_config->get_dash_fragment(r->vhost);
|
||||
home = _srs_config->get_dash_path(r->vhost);
|
||||
|
|
@ -737,7 +737,7 @@ srs_utime_t SrsDash::cleanup_delay()
|
|||
return _srs_config->get_dash_dispose(req->vhost) * 1.1;
|
||||
}
|
||||
|
||||
srs_error_t SrsDash::initialize(SrsOriginHub *h, SrsRequest *r)
|
||||
srs_error_t SrsDash::initialize(SrsOriginHub *h, ISrsRequest *r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include <srs_app_fragment.hpp>
|
||||
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsOriginHub;
|
||||
class SrsSharedPtrMessage;
|
||||
class SrsFormat;
|
||||
|
|
@ -52,7 +52,7 @@ public:
|
|||
|
||||
public:
|
||||
// Initialize the fragment, create the home dir, open the file.
|
||||
virtual srs_error_t initialize(SrsRequest *r, bool video, int64_t time, SrsMpdWriter *mpd, uint32_t tid);
|
||||
virtual srs_error_t initialize(ISrsRequest *r, bool video, int64_t time, SrsMpdWriter *mpd, uint32_t tid);
|
||||
// Write media message to fragment.
|
||||
virtual srs_error_t write(SrsSharedPtrMessage *shared_msg, SrsFormat *format);
|
||||
// Reap the fragment, close the fd and rename tmp to official file.
|
||||
|
|
@ -63,7 +63,7 @@ public:
|
|||
class SrsMpdWriter
|
||||
{
|
||||
private:
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
|
||||
private:
|
||||
// The duration of fragment in srs_utime_t.
|
||||
|
|
@ -97,7 +97,7 @@ public:
|
|||
virtual void dispose();
|
||||
|
||||
public:
|
||||
virtual srs_error_t initialize(SrsRequest *r);
|
||||
virtual srs_error_t initialize(ISrsRequest *r);
|
||||
virtual srs_error_t on_publish();
|
||||
virtual void on_unpublish();
|
||||
// Write MPD according to parsed format of stream.
|
||||
|
|
@ -116,7 +116,7 @@ public:
|
|||
class SrsDashController
|
||||
{
|
||||
private:
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
SrsFormat *format_;
|
||||
SrsMpdWriter *mpd;
|
||||
|
||||
|
|
@ -151,7 +151,7 @@ public:
|
|||
virtual void dispose();
|
||||
|
||||
public:
|
||||
virtual srs_error_t initialize(SrsRequest *r);
|
||||
virtual srs_error_t initialize(ISrsRequest *r);
|
||||
virtual srs_error_t on_publish();
|
||||
virtual void on_unpublish();
|
||||
virtual srs_error_t on_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format);
|
||||
|
|
@ -171,7 +171,7 @@ private:
|
|||
srs_utime_t last_update_time_;
|
||||
|
||||
private:
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
SrsOriginHub *hub;
|
||||
SrsDashController *controller;
|
||||
|
||||
|
|
@ -186,7 +186,7 @@ public:
|
|||
|
||||
public:
|
||||
// Initalize the encoder.
|
||||
virtual srs_error_t initialize(SrsOriginHub *h, SrsRequest *r);
|
||||
virtual srs_error_t initialize(SrsOriginHub *h, ISrsRequest *r);
|
||||
// When stream start publishing.
|
||||
virtual srs_error_t on_publish();
|
||||
// When got an shared audio message.
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ SrsDvrSegmenter::~SrsDvrSegmenter()
|
|||
srs_freep(fs);
|
||||
}
|
||||
|
||||
srs_error_t SrsDvrSegmenter::initialize(SrsDvrPlan *p, SrsRequest *r)
|
||||
srs_error_t SrsDvrSegmenter::initialize(SrsDvrPlan *p, ISrsRequest *r)
|
||||
{
|
||||
req = r;
|
||||
plan = p;
|
||||
|
|
@ -517,7 +517,7 @@ srs_error_t SrsDvrMp4Segmenter::close_encoder()
|
|||
return err;
|
||||
}
|
||||
|
||||
SrsDvrAsyncCallOnDvr::SrsDvrAsyncCallOnDvr(SrsContextId c, SrsRequest *r, string p)
|
||||
SrsDvrAsyncCallOnDvr::SrsDvrAsyncCallOnDvr(SrsContextId c, ISrsRequest *r, string p)
|
||||
{
|
||||
cid = c;
|
||||
req = r->copy();
|
||||
|
|
@ -581,7 +581,7 @@ SrsDvrPlan::~SrsDvrPlan()
|
|||
srs_freep(req);
|
||||
}
|
||||
|
||||
srs_error_t SrsDvrPlan::initialize(SrsOriginHub *h, SrsDvrSegmenter *s, SrsRequest *r)
|
||||
srs_error_t SrsDvrPlan::initialize(SrsOriginHub *h, SrsDvrSegmenter *s, ISrsRequest *r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -596,7 +596,7 @@ srs_error_t SrsDvrPlan::initialize(SrsOriginHub *h, SrsDvrSegmenter *s, SrsReque
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsDvrPlan::on_publish(SrsRequest *r)
|
||||
srs_error_t SrsDvrPlan::on_publish(ISrsRequest *r)
|
||||
{
|
||||
// @see https://github.com/ossrs/srs/issues/1613#issuecomment-960623359
|
||||
srs_freep(req);
|
||||
|
|
@ -689,7 +689,7 @@ SrsDvrSessionPlan::~SrsDvrSessionPlan()
|
|||
{
|
||||
}
|
||||
|
||||
srs_error_t SrsDvrSessionPlan::on_publish(SrsRequest *r)
|
||||
srs_error_t SrsDvrSessionPlan::on_publish(ISrsRequest *r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -751,7 +751,7 @@ SrsDvrSegmentPlan::~SrsDvrSegmentPlan()
|
|||
{
|
||||
}
|
||||
|
||||
srs_error_t SrsDvrSegmentPlan::initialize(SrsOriginHub *h, SrsDvrSegmenter *s, SrsRequest *r)
|
||||
srs_error_t SrsDvrSegmentPlan::initialize(SrsOriginHub *h, SrsDvrSegmenter *s, ISrsRequest *r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -766,7 +766,7 @@ srs_error_t SrsDvrSegmentPlan::initialize(SrsOriginHub *h, SrsDvrSegmenter *s, S
|
|||
return srs_success;
|
||||
}
|
||||
|
||||
srs_error_t SrsDvrSegmentPlan::on_publish(SrsRequest *r)
|
||||
srs_error_t SrsDvrSegmentPlan::on_publish(ISrsRequest *r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -932,7 +932,7 @@ SrsDvr::~SrsDvr()
|
|||
srs_freep(req);
|
||||
}
|
||||
|
||||
srs_error_t SrsDvr::initialize(SrsOriginHub *h, SrsRequest *r)
|
||||
srs_error_t SrsDvr::initialize(SrsOriginHub *h, ISrsRequest *r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -962,7 +962,7 @@ srs_error_t SrsDvr::initialize(SrsOriginHub *h, SrsRequest *r)
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsDvr::on_publish(SrsRequest *r)
|
||||
srs_error_t SrsDvr::on_publish(ISrsRequest *r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
class SrsLiveSource;
|
||||
class SrsOriginHub;
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsBuffer;
|
||||
class SrsRtmpJitter;
|
||||
class SrsSharedPtrMessage;
|
||||
|
|
@ -44,7 +44,7 @@ protected:
|
|||
SrsFragment *fragment;
|
||||
|
||||
private:
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
SrsDvrPlan *plan;
|
||||
|
||||
private:
|
||||
|
|
@ -57,7 +57,7 @@ public:
|
|||
|
||||
public:
|
||||
// Initialize the segment.
|
||||
virtual srs_error_t initialize(SrsDvrPlan *p, SrsRequest *r);
|
||||
virtual srs_error_t initialize(SrsDvrPlan *p, ISrsRequest *r);
|
||||
// Get the current framgnet.
|
||||
virtual SrsFragment *current();
|
||||
// Open new segment file.
|
||||
|
|
@ -157,10 +157,10 @@ class SrsDvrAsyncCallOnDvr : public ISrsAsyncCallTask
|
|||
private:
|
||||
SrsContextId cid;
|
||||
std::string path;
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
|
||||
public:
|
||||
SrsDvrAsyncCallOnDvr(SrsContextId c, SrsRequest *r, std::string p);
|
||||
SrsDvrAsyncCallOnDvr(SrsContextId c, ISrsRequest *r, std::string p);
|
||||
virtual ~SrsDvrAsyncCallOnDvr();
|
||||
|
||||
public:
|
||||
|
|
@ -172,7 +172,7 @@ public:
|
|||
class SrsDvrPlan : public ISrsReloadHandler
|
||||
{
|
||||
public:
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
|
||||
protected:
|
||||
SrsOriginHub *hub;
|
||||
|
|
@ -184,8 +184,8 @@ public:
|
|||
virtual ~SrsDvrPlan();
|
||||
|
||||
public:
|
||||
virtual srs_error_t initialize(SrsOriginHub *h, SrsDvrSegmenter *s, SrsRequest *r);
|
||||
virtual srs_error_t on_publish(SrsRequest *r);
|
||||
virtual srs_error_t initialize(SrsOriginHub *h, SrsDvrSegmenter *s, ISrsRequest *r);
|
||||
virtual srs_error_t on_publish(ISrsRequest *r);
|
||||
virtual void on_unpublish();
|
||||
virtual srs_error_t on_meta_data(SrsSharedPtrMessage *shared_metadata);
|
||||
virtual srs_error_t on_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format);
|
||||
|
|
@ -207,7 +207,7 @@ public:
|
|||
virtual ~SrsDvrSessionPlan();
|
||||
|
||||
public:
|
||||
virtual srs_error_t on_publish(SrsRequest *r);
|
||||
virtual srs_error_t on_publish(ISrsRequest *r);
|
||||
virtual void on_unpublish();
|
||||
};
|
||||
|
||||
|
|
@ -226,8 +226,8 @@ public:
|
|||
virtual ~SrsDvrSegmentPlan();
|
||||
|
||||
public:
|
||||
virtual srs_error_t initialize(SrsOriginHub *h, SrsDvrSegmenter *s, SrsRequest *r);
|
||||
virtual srs_error_t on_publish(SrsRequest *r);
|
||||
virtual srs_error_t initialize(SrsOriginHub *h, SrsDvrSegmenter *s, ISrsRequest *r);
|
||||
virtual srs_error_t on_publish(ISrsRequest *r);
|
||||
virtual void on_unpublish();
|
||||
virtual srs_error_t on_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format);
|
||||
virtual srs_error_t on_video(SrsSharedPtrMessage *shared_video, SrsFormat *format);
|
||||
|
|
@ -245,7 +245,7 @@ class SrsDvr : public ISrsReloadHandler
|
|||
private:
|
||||
SrsOriginHub *hub;
|
||||
SrsDvrPlan *plan;
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
|
||||
private:
|
||||
// whether the dvr is actived by filter, which is specified by dvr_apply.
|
||||
|
|
@ -261,11 +261,11 @@ public:
|
|||
// initialize dvr, create dvr plan.
|
||||
// when system initialize(encoder publish at first time, or reload),
|
||||
// initialize the dvr will reinitialize the plan, the whole dvr framework.
|
||||
virtual srs_error_t initialize(SrsOriginHub *h, SrsRequest *r);
|
||||
virtual srs_error_t initialize(SrsOriginHub *h, ISrsRequest *r);
|
||||
// publish stream event,
|
||||
// when encoder start to publish RTMP stream.
|
||||
// @param fetch_sequence_header whether fetch sequence from source.
|
||||
virtual srs_error_t on_publish(SrsRequest *r);
|
||||
virtual srs_error_t on_publish(ISrsRequest *r);
|
||||
// the unpublish event.,
|
||||
// when encoder stop(unpublish) to publish RTMP stream.
|
||||
virtual void on_unpublish();
|
||||
|
|
|
|||
|
|
@ -62,11 +62,11 @@ SrsEdgeRtmpUpstream::~SrsEdgeRtmpUpstream()
|
|||
close();
|
||||
}
|
||||
|
||||
srs_error_t SrsEdgeRtmpUpstream::connect(SrsRequest *r, SrsLbRoundRobin *lb)
|
||||
srs_error_t SrsEdgeRtmpUpstream::connect(ISrsRequest *r, SrsLbRoundRobin *lb)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = r;
|
||||
ISrsRequest *req = r;
|
||||
|
||||
std::string url;
|
||||
if (true) {
|
||||
|
|
@ -178,10 +178,10 @@ SrsEdgeFlvUpstream::~SrsEdgeFlvUpstream()
|
|||
close();
|
||||
}
|
||||
|
||||
srs_error_t SrsEdgeFlvUpstream::connect(SrsRequest *r, SrsLbRoundRobin *lb)
|
||||
srs_error_t SrsEdgeFlvUpstream::connect(ISrsRequest *r, SrsLbRoundRobin *lb)
|
||||
{
|
||||
// Because we might modify the r, which cause retry fail, so we must copy it.
|
||||
SrsRequest *cp = r->copy();
|
||||
ISrsRequest *cp = r->copy();
|
||||
|
||||
// Free the request when close upstream.
|
||||
srs_freep(req_);
|
||||
|
|
@ -190,11 +190,11 @@ srs_error_t SrsEdgeFlvUpstream::connect(SrsRequest *r, SrsLbRoundRobin *lb)
|
|||
return do_connect(cp, lb, 0);
|
||||
}
|
||||
|
||||
srs_error_t SrsEdgeFlvUpstream::do_connect(SrsRequest *r, SrsLbRoundRobin *lb, int redirect_depth)
|
||||
srs_error_t SrsEdgeFlvUpstream::do_connect(ISrsRequest *r, SrsLbRoundRobin *lb, int redirect_depth)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = r;
|
||||
ISrsRequest *req = r;
|
||||
|
||||
if (redirect_depth == 0) {
|
||||
SrsConfDirective *conf = _srs_config->get_vhost_edge_origin(req->vhost);
|
||||
|
|
@ -417,7 +417,7 @@ SrsEdgeIngester::~SrsEdgeIngester()
|
|||
srs_freep(trd);
|
||||
}
|
||||
|
||||
srs_error_t SrsEdgeIngester::initialize(SrsSharedPtr<SrsLiveSource> s, SrsPlayEdge *e, SrsRequest *r)
|
||||
srs_error_t SrsEdgeIngester::initialize(SrsSharedPtr<SrsLiveSource> s, SrsPlayEdge *e, ISrsRequest *r)
|
||||
{
|
||||
// Because source references to this object, so we should directly use the source ptr.
|
||||
source_ = s.get();
|
||||
|
|
@ -750,7 +750,7 @@ void SrsEdgeForwarder::set_queue_size(srs_utime_t queue_size)
|
|||
return queue->set_queue_size(queue_size);
|
||||
}
|
||||
|
||||
srs_error_t SrsEdgeForwarder::initialize(SrsSharedPtr<SrsLiveSource> s, SrsPublishEdge *e, SrsRequest *r)
|
||||
srs_error_t SrsEdgeForwarder::initialize(SrsSharedPtr<SrsLiveSource> s, SrsPublishEdge *e, ISrsRequest *r)
|
||||
{
|
||||
// Because source references to this object, so we should directly use the source ptr.
|
||||
source_ = s.get();
|
||||
|
|
@ -965,7 +965,7 @@ SrsPlayEdge::~SrsPlayEdge()
|
|||
srs_freep(ingester);
|
||||
}
|
||||
|
||||
srs_error_t SrsPlayEdge::initialize(SrsSharedPtr<SrsLiveSource> source, SrsRequest *req)
|
||||
srs_error_t SrsPlayEdge::initialize(SrsSharedPtr<SrsLiveSource> source, ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -1058,7 +1058,7 @@ void SrsPublishEdge::set_queue_size(srs_utime_t queue_size)
|
|||
return forwarder->set_queue_size(queue_size);
|
||||
}
|
||||
|
||||
srs_error_t SrsPublishEdge::initialize(SrsSharedPtr<SrsLiveSource> source, SrsRequest *req)
|
||||
srs_error_t SrsPublishEdge::initialize(SrsSharedPtr<SrsLiveSource> source, ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
class SrsStSocket;
|
||||
class SrsRtmpServer;
|
||||
class SrsLiveSource;
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsPlayEdge;
|
||||
class SrsPublishEdge;
|
||||
class SrsRtmpClient;
|
||||
|
|
@ -65,7 +65,7 @@ public:
|
|||
virtual ~SrsEdgeUpstream();
|
||||
|
||||
public:
|
||||
virtual srs_error_t connect(SrsRequest *r, SrsLbRoundRobin *lb) = 0;
|
||||
virtual srs_error_t connect(ISrsRequest *r, SrsLbRoundRobin *lb) = 0;
|
||||
virtual srs_error_t recv_message(SrsCommonMessage **pmsg) = 0;
|
||||
virtual srs_error_t decode_message(SrsCommonMessage *msg, SrsPacket **ppacket) = 0;
|
||||
virtual void close() = 0;
|
||||
|
|
@ -95,7 +95,7 @@ public:
|
|||
virtual ~SrsEdgeRtmpUpstream();
|
||||
|
||||
public:
|
||||
virtual srs_error_t connect(SrsRequest *r, SrsLbRoundRobin *lb);
|
||||
virtual srs_error_t connect(ISrsRequest *r, SrsLbRoundRobin *lb);
|
||||
virtual srs_error_t recv_message(SrsCommonMessage **pmsg);
|
||||
virtual srs_error_t decode_message(SrsCommonMessage *msg, SrsPacket **ppacket);
|
||||
virtual void close();
|
||||
|
|
@ -119,7 +119,7 @@ private:
|
|||
|
||||
private:
|
||||
// We might modify the request by HTTP redirect.
|
||||
SrsRequest *req_;
|
||||
ISrsRequest *req_;
|
||||
// Current selected server, the ip:port.
|
||||
std::string selected_ip;
|
||||
int selected_port;
|
||||
|
|
@ -129,10 +129,10 @@ public:
|
|||
virtual ~SrsEdgeFlvUpstream();
|
||||
|
||||
public:
|
||||
virtual srs_error_t connect(SrsRequest *r, SrsLbRoundRobin *lb);
|
||||
virtual srs_error_t connect(ISrsRequest *r, SrsLbRoundRobin *lb);
|
||||
|
||||
private:
|
||||
virtual srs_error_t do_connect(SrsRequest *r, SrsLbRoundRobin *lb, int redirect_depth);
|
||||
virtual srs_error_t do_connect(ISrsRequest *r, SrsLbRoundRobin *lb, int redirect_depth);
|
||||
|
||||
public:
|
||||
virtual srs_error_t recv_message(SrsCommonMessage **pmsg);
|
||||
|
|
@ -154,7 +154,7 @@ private:
|
|||
|
||||
private:
|
||||
SrsPlayEdge *edge;
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
SrsCoroutine *trd;
|
||||
SrsLbRoundRobin *lb;
|
||||
SrsEdgeUpstream *upstream;
|
||||
|
|
@ -166,7 +166,7 @@ public:
|
|||
virtual ~SrsEdgeIngester();
|
||||
|
||||
public:
|
||||
virtual srs_error_t initialize(SrsSharedPtr<SrsLiveSource> s, SrsPlayEdge *e, SrsRequest *r);
|
||||
virtual srs_error_t initialize(SrsSharedPtr<SrsLiveSource> s, SrsPlayEdge *e, ISrsRequest *r);
|
||||
virtual srs_error_t start();
|
||||
virtual void stop();
|
||||
virtual std::string get_curr_origin();
|
||||
|
|
@ -195,7 +195,7 @@ private:
|
|||
|
||||
private:
|
||||
SrsPublishEdge *edge;
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
SrsCoroutine *trd;
|
||||
SrsSimpleRtmpClient *sdk;
|
||||
SrsLbRoundRobin *lb;
|
||||
|
|
@ -215,7 +215,7 @@ public:
|
|||
virtual void set_queue_size(srs_utime_t queue_size);
|
||||
|
||||
public:
|
||||
virtual srs_error_t initialize(SrsSharedPtr<SrsLiveSource> s, SrsPublishEdge *e, SrsRequest *r);
|
||||
virtual srs_error_t initialize(SrsSharedPtr<SrsLiveSource> s, SrsPublishEdge *e, ISrsRequest *r);
|
||||
virtual srs_error_t start();
|
||||
virtual void stop();
|
||||
// Interface ISrsReusableThread2Handler
|
||||
|
|
@ -244,7 +244,7 @@ public:
|
|||
// Always use the req of source,
|
||||
// For we assume all client to edge is invalid,
|
||||
// if auth open, edge must valid it from origin, then service it.
|
||||
virtual srs_error_t initialize(SrsSharedPtr<SrsLiveSource> source, SrsRequest *req);
|
||||
virtual srs_error_t initialize(SrsSharedPtr<SrsLiveSource> source, ISrsRequest *req);
|
||||
// When client play stream on edge.
|
||||
virtual srs_error_t on_client_play();
|
||||
// When all client stopped play, disconnect to origin.
|
||||
|
|
@ -271,7 +271,7 @@ public:
|
|||
virtual void set_queue_size(srs_utime_t queue_size);
|
||||
|
||||
public:
|
||||
virtual srs_error_t initialize(SrsSharedPtr<SrsLiveSource> source, SrsRequest *req);
|
||||
virtual srs_error_t initialize(SrsSharedPtr<SrsLiveSource> source, ISrsRequest *req);
|
||||
virtual bool can_publish();
|
||||
// When client publish stream on edge.
|
||||
virtual srs_error_t on_client_publish();
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ SrsEncoder::~SrsEncoder()
|
|||
srs_freep(pprint);
|
||||
}
|
||||
|
||||
srs_error_t SrsEncoder::on_publish(SrsRequest *req)
|
||||
srs_error_t SrsEncoder::on_publish(ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -155,7 +155,7 @@ SrsFFMPEG *SrsEncoder::at(int index)
|
|||
return ffmpegs[index];
|
||||
}
|
||||
|
||||
srs_error_t SrsEncoder::parse_scope_engines(SrsRequest *req)
|
||||
srs_error_t SrsEncoder::parse_scope_engines(ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -188,7 +188,7 @@ srs_error_t SrsEncoder::parse_scope_engines(SrsRequest *req)
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsEncoder::parse_ffmpeg(SrsRequest *req, SrsConfDirective *conf)
|
||||
srs_error_t SrsEncoder::parse_ffmpeg(ISrsRequest *req, SrsConfDirective *conf)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -234,7 +234,7 @@ srs_error_t SrsEncoder::parse_ffmpeg(SrsRequest *req, SrsConfDirective *conf)
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsEncoder::initialize_ffmpeg(SrsFFMPEG *ffmpeg, SrsRequest *req, SrsConfDirective *engine)
|
||||
srs_error_t SrsEncoder::initialize_ffmpeg(SrsFFMPEG *ffmpeg, ISrsRequest *req, SrsConfDirective *engine)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
#include <srs_app_st.hpp>
|
||||
|
||||
class SrsConfDirective;
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsPithyPrint;
|
||||
class SrsFFMPEG;
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ public:
|
|||
virtual ~SrsEncoder();
|
||||
|
||||
public:
|
||||
virtual srs_error_t on_publish(SrsRequest *req);
|
||||
virtual srs_error_t on_publish(ISrsRequest *req);
|
||||
virtual void on_unpublish();
|
||||
// Interface ISrsReusableThreadHandler.
|
||||
public:
|
||||
|
|
@ -48,9 +48,9 @@ private:
|
|||
private:
|
||||
virtual void clear_engines();
|
||||
virtual SrsFFMPEG *at(int index);
|
||||
virtual srs_error_t parse_scope_engines(SrsRequest *req);
|
||||
virtual srs_error_t parse_ffmpeg(SrsRequest *req, SrsConfDirective *conf);
|
||||
virtual srs_error_t initialize_ffmpeg(SrsFFMPEG *ffmpeg, SrsRequest *req, SrsConfDirective *engine);
|
||||
virtual srs_error_t parse_scope_engines(ISrsRequest *req);
|
||||
virtual srs_error_t parse_ffmpeg(ISrsRequest *req, SrsConfDirective *conf);
|
||||
virtual srs_error_t initialize_ffmpeg(SrsFFMPEG *ffmpeg, ISrsRequest *req, SrsConfDirective *engine);
|
||||
virtual void show_encode_log_message();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ SrsForwarder::~SrsForwarder()
|
|||
srs_freep(req);
|
||||
}
|
||||
|
||||
srs_error_t SrsForwarder::initialize(SrsRequest *r, string ep)
|
||||
srs_error_t SrsForwarder::initialize(ISrsRequest *r, string ep)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class SrsOnMetaDataPacket;
|
|||
class SrsMessageQueue;
|
||||
class SrsRtmpJitter;
|
||||
class SrsRtmpClient;
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsLiveSource;
|
||||
class SrsOriginHub;
|
||||
class SrsKbps;
|
||||
|
|
@ -31,7 +31,7 @@ class SrsForwarder : public ISrsCoroutineHandler
|
|||
private:
|
||||
// The ep to forward, server[:port].
|
||||
std::string ep_forward;
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
|
||||
private:
|
||||
// The source or stream context id to bind to.
|
||||
|
|
@ -54,7 +54,7 @@ public:
|
|||
virtual ~SrsForwarder();
|
||||
|
||||
public:
|
||||
virtual srs_error_t initialize(SrsRequest *r, std::string ep);
|
||||
virtual srs_error_t initialize(ISrsRequest *r, std::string ep);
|
||||
virtual void set_queue_size(srs_utime_t queue_size);
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ string serialFlv(SrsSharedPtrMessage *msg)
|
|||
class SrsHdsFragment
|
||||
{
|
||||
public:
|
||||
SrsHdsFragment(SrsRequest *r)
|
||||
SrsHdsFragment(ISrsRequest *r)
|
||||
: req(r), index(-1), start_time(0), videoSh(NULL), audioSh(NULL)
|
||||
{
|
||||
}
|
||||
|
|
@ -218,7 +218,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
list<SrsSharedPtrMessage *> msgs;
|
||||
|
||||
/*!
|
||||
|
|
@ -241,7 +241,7 @@ SrsHds::~SrsHds()
|
|||
{
|
||||
}
|
||||
|
||||
srs_error_t SrsHds::on_publish(SrsRequest *req)
|
||||
srs_error_t SrsHds::on_publish(ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
#include <list>
|
||||
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsSharedPtrMessage;
|
||||
class SrsHdsFragment;
|
||||
class SrsLiveSource;
|
||||
|
|
@ -25,7 +25,7 @@ public:
|
|||
SrsHds();
|
||||
virtual ~SrsHds();
|
||||
|
||||
srs_error_t on_publish(SrsRequest *req);
|
||||
srs_error_t on_publish(ISrsRequest *req);
|
||||
srs_error_t on_unpublish();
|
||||
|
||||
srs_error_t on_video(SrsSharedPtrMessage *msg);
|
||||
|
|
@ -43,7 +43,7 @@ private:
|
|||
SrsSharedPtrMessage *video_sh;
|
||||
SrsSharedPtrMessage *audio_sh;
|
||||
|
||||
SrsRequest *hds_req;
|
||||
ISrsRequest *hds_req;
|
||||
bool hds_enabled;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ srs_error_t SrsHlsM4sSegment::reap(uint64_t dts)
|
|||
return err;
|
||||
}
|
||||
|
||||
SrsDvrAsyncCallOnHls::SrsDvrAsyncCallOnHls(SrsContextId c, SrsRequest *r, string p, string t, string m, string mu, int s, srs_utime_t d)
|
||||
SrsDvrAsyncCallOnHls::SrsDvrAsyncCallOnHls(SrsContextId c, ISrsRequest *r, string p, string t, string m, string mu, int s, srs_utime_t d)
|
||||
{
|
||||
req = r->copy();
|
||||
cid = c;
|
||||
|
|
@ -309,7 +309,7 @@ string SrsDvrAsyncCallOnHls::to_string()
|
|||
return "on_hls: " + path;
|
||||
}
|
||||
|
||||
SrsDvrAsyncCallOnHlsNotify::SrsDvrAsyncCallOnHlsNotify(SrsContextId c, SrsRequest *r, string u)
|
||||
SrsDvrAsyncCallOnHlsNotify::SrsDvrAsyncCallOnHlsNotify(SrsContextId c, ISrsRequest *r, string u)
|
||||
{
|
||||
cid = c;
|
||||
req = r->copy();
|
||||
|
|
@ -473,7 +473,7 @@ srs_error_t SrsHlsFmp4Muxer::initialize(int v_tid, int a_tid)
|
|||
return srs_success;
|
||||
}
|
||||
|
||||
srs_error_t SrsHlsFmp4Muxer::on_publish(SrsRequest *req)
|
||||
srs_error_t SrsHlsFmp4Muxer::on_publish(ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -632,7 +632,7 @@ srs_error_t SrsHlsFmp4Muxer::on_unpublish()
|
|||
return srs_success;
|
||||
}
|
||||
|
||||
srs_error_t SrsHlsFmp4Muxer::update_config(SrsRequest *r)
|
||||
srs_error_t SrsHlsFmp4Muxer::update_config(ISrsRequest *r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -1177,7 +1177,7 @@ srs_error_t SrsHlsMuxer::initialize()
|
|||
return srs_success;
|
||||
}
|
||||
|
||||
srs_error_t SrsHlsMuxer::on_publish(SrsRequest *req)
|
||||
srs_error_t SrsHlsMuxer::on_publish(ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -1194,7 +1194,7 @@ srs_error_t SrsHlsMuxer::on_unpublish()
|
|||
return srs_success;
|
||||
}
|
||||
|
||||
srs_error_t SrsHlsMuxer::update_config(SrsRequest *r, string entry_prefix,
|
||||
srs_error_t SrsHlsMuxer::update_config(ISrsRequest *r, string entry_prefix,
|
||||
string path, string m3u8_file, string ts_file, srs_utime_t fragment, srs_utime_t window,
|
||||
bool ts_floor, double aof_ratio, bool cleanup, bool wait_keyframe, bool keys,
|
||||
int fragments_per_key, string key_file, string key_file_path, string key_url)
|
||||
|
|
@ -1935,7 +1935,7 @@ int SrsHlsController::deviation()
|
|||
return muxer->deviation();
|
||||
}
|
||||
|
||||
srs_error_t SrsHlsController::on_publish(SrsRequest *req)
|
||||
srs_error_t SrsHlsController::on_publish(ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -2239,7 +2239,7 @@ void SrsHlsMp4Controller::dispose()
|
|||
muxer_->dispose();
|
||||
}
|
||||
|
||||
srs_error_t SrsHlsMp4Controller::on_publish(SrsRequest *req)
|
||||
srs_error_t SrsHlsMp4Controller::on_publish(ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -2514,7 +2514,7 @@ srs_utime_t SrsHls::cleanup_delay()
|
|||
return _srs_config->get_hls_dispose(req->vhost) * 1.1;
|
||||
}
|
||||
|
||||
srs_error_t SrsHls::initialize(SrsOriginHub *h, SrsRequest *r)
|
||||
srs_error_t SrsHls::initialize(SrsOriginHub *h, ISrsRequest *r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class SrsSharedPtrMessage;
|
|||
class SrsAmf0Object;
|
||||
class SrsRtmpJitter;
|
||||
class SrsTsContextWriter;
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsPithyPrint;
|
||||
class SrsLiveSource;
|
||||
class SrsOriginHub;
|
||||
|
|
@ -132,12 +132,12 @@ private:
|
|||
std::string m3u8;
|
||||
std::string m3u8_url;
|
||||
int seq_no;
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
srs_utime_t duration;
|
||||
|
||||
public:
|
||||
// TODO: FIXME: Use TBN 1000.
|
||||
SrsDvrAsyncCallOnHls(SrsContextId c, SrsRequest *r, std::string p, std::string t, std::string m, std::string mu, int s, srs_utime_t d);
|
||||
SrsDvrAsyncCallOnHls(SrsContextId c, ISrsRequest *r, std::string p, std::string t, std::string m, std::string mu, int s, srs_utime_t d);
|
||||
virtual ~SrsDvrAsyncCallOnHls();
|
||||
|
||||
public:
|
||||
|
|
@ -151,10 +151,10 @@ class SrsDvrAsyncCallOnHlsNotify : public ISrsAsyncCallTask
|
|||
private:
|
||||
SrsContextId cid;
|
||||
std::string ts_url;
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
|
||||
public:
|
||||
SrsDvrAsyncCallOnHlsNotify(SrsContextId c, SrsRequest *r, std::string u);
|
||||
SrsDvrAsyncCallOnHlsNotify(SrsContextId c, ISrsRequest *r, std::string u);
|
||||
virtual ~SrsDvrAsyncCallOnHlsNotify();
|
||||
|
||||
public:
|
||||
|
|
@ -172,7 +172,7 @@ public:
|
|||
class SrsHlsMuxer
|
||||
{
|
||||
private:
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
|
||||
private:
|
||||
std::string hls_entry_prefix;
|
||||
|
|
@ -257,10 +257,10 @@ public:
|
|||
// Initialize the hls muxer.
|
||||
virtual srs_error_t initialize();
|
||||
// When publish or unpublish stream.
|
||||
virtual srs_error_t on_publish(SrsRequest *req);
|
||||
virtual srs_error_t on_publish(ISrsRequest *req);
|
||||
virtual srs_error_t on_unpublish();
|
||||
// When publish, update the config for muxer.
|
||||
virtual srs_error_t update_config(SrsRequest *r, std::string entry_prefix,
|
||||
virtual srs_error_t update_config(ISrsRequest *r, std::string entry_prefix,
|
||||
std::string path, std::string m3u8_file, std::string ts_file,
|
||||
srs_utime_t fragment, srs_utime_t window, bool ts_floor, double aof_ratio,
|
||||
bool cleanup, bool wait_keyframe, bool keys, int fragments_per_key,
|
||||
|
|
@ -308,7 +308,7 @@ public:
|
|||
class SrsHlsFmp4Muxer
|
||||
{
|
||||
private:
|
||||
SrsRequest *req_;
|
||||
ISrsRequest *req_;
|
||||
|
||||
private:
|
||||
std::string hls_entry_prefix_;
|
||||
|
|
@ -406,7 +406,7 @@ public:
|
|||
// Initialize the hls muxer.
|
||||
virtual srs_error_t initialize(int v_tid, int a_tid);
|
||||
// When publish or unpublish stream.
|
||||
virtual srs_error_t on_publish(SrsRequest *req);
|
||||
virtual srs_error_t on_publish(ISrsRequest *req);
|
||||
|
||||
public:
|
||||
virtual srs_error_t write_init_mp4(SrsFormat *format, bool has_video, bool has_audio);
|
||||
|
|
@ -416,7 +416,7 @@ public:
|
|||
public:
|
||||
virtual srs_error_t on_unpublish();
|
||||
// When publish, update the config for muxer.
|
||||
virtual srs_error_t update_config(SrsRequest *r);
|
||||
virtual srs_error_t update_config(ISrsRequest *r);
|
||||
// Open a new segment(a new ts file)
|
||||
virtual srs_error_t segment_open(srs_utime_t basetime);
|
||||
virtual srs_error_t on_sequence_header();
|
||||
|
|
@ -455,7 +455,7 @@ public:
|
|||
virtual srs_error_t initialize() = 0;
|
||||
virtual void dispose() = 0;
|
||||
// When publish or unpublish stream.
|
||||
virtual srs_error_t on_publish(SrsRequest *req) = 0;
|
||||
virtual srs_error_t on_publish(ISrsRequest *req) = 0;
|
||||
virtual srs_error_t on_unpublish() = 0;
|
||||
|
||||
public:
|
||||
|
|
@ -518,7 +518,7 @@ public:
|
|||
|
||||
public:
|
||||
// When publish or unpublish stream.
|
||||
virtual srs_error_t on_publish(SrsRequest *req);
|
||||
virtual srs_error_t on_publish(ISrsRequest *req);
|
||||
virtual srs_error_t on_unpublish();
|
||||
// When get sequence header,
|
||||
// must write a #EXT-X-DISCONTINUITY to m3u8.
|
||||
|
|
@ -557,7 +557,7 @@ private:
|
|||
uint64_t video_dts_;
|
||||
|
||||
private:
|
||||
SrsRequest *req_;
|
||||
ISrsRequest *req_;
|
||||
|
||||
private:
|
||||
SrsHlsFmp4Muxer *muxer_;
|
||||
|
|
@ -570,7 +570,7 @@ public:
|
|||
virtual srs_error_t initialize();
|
||||
virtual void dispose();
|
||||
// When publish or unpublish stream.
|
||||
virtual srs_error_t on_publish(SrsRequest *req);
|
||||
virtual srs_error_t on_publish(ISrsRequest *req);
|
||||
virtual srs_error_t on_unpublish();
|
||||
virtual srs_error_t write_audio(SrsSharedPtrMessage *shared_audio, SrsFormat *format);
|
||||
virtual srs_error_t write_video(SrsSharedPtrMessage *shared_video, SrsFormat *format);
|
||||
|
|
@ -591,7 +591,7 @@ private:
|
|||
ISrsHlsController *controller;
|
||||
|
||||
private:
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
// Whether the HLS is enabled.
|
||||
bool enabled;
|
||||
// Whether the HLS stream is able to be disposed.
|
||||
|
|
@ -627,7 +627,7 @@ public:
|
|||
|
||||
public:
|
||||
// Initialize the hls by handler and source.
|
||||
virtual srs_error_t initialize(SrsOriginHub *h, SrsRequest *r);
|
||||
virtual srs_error_t initialize(SrsOriginHub *h, ISrsRequest *r);
|
||||
// Publish stream event, continue to write the m3u8,
|
||||
// for the muxer object not destroyed.
|
||||
// @param fetch_sequence_header whether fetch sequence from source.
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ class SrsServer;
|
|||
class SrsRtcServer;
|
||||
class SrsJsonObject;
|
||||
class SrsSdp;
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class ISrsHttpResponseWriter;
|
||||
class SrsHttpConn;
|
||||
|
||||
|
|
|
|||
|
|
@ -154,9 +154,9 @@ srs_error_t SrsHttpConn::do_cycle()
|
|||
}
|
||||
|
||||
// process all http messages.
|
||||
SrsRequest *last_req_raw = NULL;
|
||||
ISrsRequest *last_req_raw = NULL;
|
||||
err = process_requests(&last_req_raw);
|
||||
SrsUniquePtr<SrsRequest> last_req(last_req_raw);
|
||||
SrsUniquePtr<ISrsRequest> last_req(last_req_raw);
|
||||
|
||||
srs_error_t r0 = srs_success;
|
||||
if ((r0 = on_disconnect(last_req.get())) != srs_success) {
|
||||
|
|
@ -167,7 +167,7 @@ srs_error_t SrsHttpConn::do_cycle()
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsHttpConn::process_requests(SrsRequest **preq)
|
||||
srs_error_t SrsHttpConn::process_requests(ISrsRequest **preq)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -236,7 +236,7 @@ srs_error_t SrsHttpConn::process_request(ISrsHttpResponseWriter *w, ISrsHttpMess
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsHttpConn::on_disconnect(SrsRequest *req)
|
||||
srs_error_t SrsHttpConn::on_disconnect(ISrsRequest *req)
|
||||
{
|
||||
// TODO: FIXME: Implements it.
|
||||
return srs_success;
|
||||
|
|
@ -539,12 +539,12 @@ srs_error_t SrsHttpServer::serve_http(ISrsHttpResponseWriter *w, ISrsHttpMessage
|
|||
return http_static->mux.serve_http(w, r);
|
||||
}
|
||||
|
||||
srs_error_t SrsHttpServer::http_mount(SrsRequest *r)
|
||||
srs_error_t SrsHttpServer::http_mount(ISrsRequest *r)
|
||||
{
|
||||
return http_stream->http_mount(r);
|
||||
}
|
||||
|
||||
void SrsHttpServer::http_unmount(SrsRequest *r)
|
||||
void SrsHttpServer::http_unmount(ISrsRequest *r)
|
||||
{
|
||||
http_stream->http_unmount(r);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
class SrsServer;
|
||||
class SrsLiveSource;
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsLiveConsumer;
|
||||
class SrsStSocket;
|
||||
class SrsHttpParser;
|
||||
|
|
@ -30,7 +30,6 @@ class ISrsHttpMessage;
|
|||
class SrsHttpHandler;
|
||||
class SrsMessageQueue;
|
||||
class SrsSharedPtrMessage;
|
||||
class SrsRequest;
|
||||
class SrsFastStream;
|
||||
class SrsHttpUri;
|
||||
class SrsHttpMessage;
|
||||
|
|
@ -104,12 +103,12 @@ public:
|
|||
|
||||
private:
|
||||
virtual srs_error_t do_cycle();
|
||||
virtual srs_error_t process_requests(SrsRequest **preq);
|
||||
virtual srs_error_t process_requests(ISrsRequest **preq);
|
||||
virtual srs_error_t process_request(ISrsHttpResponseWriter *w, ISrsHttpMessage *r, int rid);
|
||||
// When the connection disconnect, call this method.
|
||||
// e.g. log msg of connection and report to other system.
|
||||
// @param request: request which is converted by the last http message.
|
||||
virtual srs_error_t on_disconnect(SrsRequest *req);
|
||||
virtual srs_error_t on_disconnect(ISrsRequest *req);
|
||||
|
||||
public:
|
||||
// Get the HTTP message handler.
|
||||
|
|
@ -202,8 +201,8 @@ public:
|
|||
virtual srs_error_t serve_http(ISrsHttpResponseWriter *w, ISrsHttpMessage *r);
|
||||
|
||||
public:
|
||||
virtual srs_error_t http_mount(SrsRequest *r);
|
||||
virtual void http_unmount(SrsRequest *r);
|
||||
virtual srs_error_t http_mount(ISrsRequest *r);
|
||||
virtual void http_unmount(ISrsRequest *r);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ SrsHttpHooks::~SrsHttpHooks()
|
|||
{
|
||||
}
|
||||
|
||||
srs_error_t SrsHttpHooks::on_connect(string url, SrsRequest *req)
|
||||
srs_error_t SrsHttpHooks::on_connect(string url, ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -88,7 +88,7 @@ srs_error_t SrsHttpHooks::on_connect(string url, SrsRequest *req)
|
|||
return err;
|
||||
}
|
||||
|
||||
void SrsHttpHooks::on_close(string url, SrsRequest *req, int64_t send_bytes, int64_t recv_bytes)
|
||||
void SrsHttpHooks::on_close(string url, ISrsRequest *req, int64_t send_bytes, int64_t recv_bytes)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -125,7 +125,7 @@ void SrsHttpHooks::on_close(string url, SrsRequest *req, int64_t send_bytes, int
|
|||
return;
|
||||
}
|
||||
|
||||
srs_error_t SrsHttpHooks::on_publish(string url, SrsRequest *req)
|
||||
srs_error_t SrsHttpHooks::on_publish(string url, ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -166,7 +166,7 @@ srs_error_t SrsHttpHooks::on_publish(string url, SrsRequest *req)
|
|||
return err;
|
||||
}
|
||||
|
||||
void SrsHttpHooks::on_unpublish(string url, SrsRequest *req)
|
||||
void SrsHttpHooks::on_unpublish(string url, ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -210,7 +210,7 @@ void SrsHttpHooks::on_unpublish(string url, SrsRequest *req)
|
|||
return;
|
||||
}
|
||||
|
||||
srs_error_t SrsHttpHooks::on_play(string url, SrsRequest *req)
|
||||
srs_error_t SrsHttpHooks::on_play(string url, ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -252,7 +252,7 @@ srs_error_t SrsHttpHooks::on_play(string url, SrsRequest *req)
|
|||
return err;
|
||||
}
|
||||
|
||||
void SrsHttpHooks::on_stop(string url, SrsRequest *req)
|
||||
void SrsHttpHooks::on_stop(string url, ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -296,7 +296,7 @@ void SrsHttpHooks::on_stop(string url, SrsRequest *req)
|
|||
return;
|
||||
}
|
||||
|
||||
srs_error_t SrsHttpHooks::on_dvr(SrsContextId c, string url, SrsRequest *req, string file)
|
||||
srs_error_t SrsHttpHooks::on_dvr(SrsContextId c, string url, ISrsRequest *req, string file)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -341,7 +341,7 @@ srs_error_t SrsHttpHooks::on_dvr(SrsContextId c, string url, SrsRequest *req, st
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsHttpHooks::on_hls(SrsContextId c, string url, SrsRequest *req, string file, string ts_url, string m3u8, string m3u8_url, int sn, srs_utime_t duration)
|
||||
srs_error_t SrsHttpHooks::on_hls(SrsContextId c, string url, ISrsRequest *req, string file, string ts_url, string m3u8, string m3u8_url, int sn, srs_utime_t duration)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -396,7 +396,7 @@ srs_error_t SrsHttpHooks::on_hls(SrsContextId c, string url, SrsRequest *req, st
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsHttpHooks::on_hls_notify(SrsContextId c, std::string url, SrsRequest *req, std::string ts_url, int nb_notify)
|
||||
srs_error_t SrsHttpHooks::on_hls_notify(SrsContextId c, std::string url, ISrsRequest *req, std::string ts_url, int nb_notify)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -520,7 +520,7 @@ srs_error_t SrsHttpHooks::discover_co_workers(string url, string &host, int &por
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsHttpHooks::on_forward_backend(string url, SrsRequest *req, std::vector<std::string> &rtmp_urls)
|
||||
srs_error_t SrsHttpHooks::on_forward_backend(string url, ISrsRequest *req, std::vector<std::string> &rtmp_urls)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
class SrsHttpUri;
|
||||
class SrsStSocket;
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsHttpParser;
|
||||
class SrsHttpClient;
|
||||
|
||||
|
|
@ -41,14 +41,14 @@ public:
|
|||
// @param url The HTTP callback URL for publish validation. If empty, hook is ignored.
|
||||
// @param req The publish request information including stream details.
|
||||
// @return srs_success if publishing is allowed, error otherwise to reject publishing.
|
||||
virtual srs_error_t on_publish(std::string url, SrsRequest *req) = 0;
|
||||
virtual srs_error_t on_publish(std::string url, ISrsRequest *req) = 0;
|
||||
|
||||
// Stream stop publishing notification hook.
|
||||
// Called when a client (encoder) stops publishing a stream.
|
||||
// This is a notification-only hook that cannot prevent the unpublishing.
|
||||
// @param url The HTTP callback URL for unpublish notification. If empty, hook is ignored.
|
||||
// @param req The unpublish request information.
|
||||
virtual void on_unpublish(std::string url, SrsRequest *req) = 0;
|
||||
virtual void on_unpublish(std::string url, ISrsRequest *req) = 0;
|
||||
|
||||
// Stream start playing validation hook.
|
||||
// Called when a client attempts to start playing/subscribing to a stream.
|
||||
|
|
@ -56,14 +56,14 @@ public:
|
|||
// @param url The HTTP callback URL for play validation. If empty, hook is ignored.
|
||||
// @param req The play request information including stream details.
|
||||
// @return srs_success if playing is allowed, error otherwise to reject playing.
|
||||
virtual srs_error_t on_play(std::string url, SrsRequest *req) = 0;
|
||||
virtual srs_error_t on_play(std::string url, ISrsRequest *req) = 0;
|
||||
|
||||
// Stream stop playing notification hook.
|
||||
// Called when a client stops playing/subscribing to a stream.
|
||||
// This is a notification-only hook that cannot prevent the stop operation.
|
||||
// @param url The HTTP callback URL for stop notification. If empty, hook is ignored.
|
||||
// @param req The stop request information.
|
||||
virtual void on_stop(std::string url, SrsRequest *req) = 0;
|
||||
virtual void on_stop(std::string url, ISrsRequest *req) = 0;
|
||||
|
||||
public:
|
||||
// DVR file completion notification hook.
|
||||
|
|
@ -75,7 +75,7 @@ public:
|
|||
// @param req The original stream request information.
|
||||
// @param file The completed DVR file path (can be relative or absolute).
|
||||
// @return srs_success if processing succeeds, error otherwise (logged but doesn't affect DVR).
|
||||
virtual srs_error_t on_dvr(SrsContextId cid, std::string url, SrsRequest *req, std::string file) = 0;
|
||||
virtual srs_error_t on_dvr(SrsContextId cid, std::string url, ISrsRequest *req, std::string file) = 0;
|
||||
|
||||
public:
|
||||
// HLS segment completion notification hook.
|
||||
|
|
@ -92,7 +92,7 @@ public:
|
|||
// @param sn The sequence number of the TS segment in the HLS playlist.
|
||||
// @param duration The segment duration in microseconds (srs_utime_t).
|
||||
// @return srs_success if processing succeeds, error otherwise (logged but doesn't affect HLS).
|
||||
virtual srs_error_t on_hls(SrsContextId cid, std::string url, SrsRequest *req, std::string file, std::string ts_url,
|
||||
virtual srs_error_t on_hls(SrsContextId cid, std::string url, ISrsRequest *req, std::string file, std::string ts_url,
|
||||
std::string m3u8, std::string m3u8_url, int sn, srs_utime_t duration) = 0;
|
||||
|
||||
// HLS segment notification hook with custom URL template.
|
||||
|
|
@ -105,7 +105,7 @@ public:
|
|||
// @param ts_url The TS segment URL to replace [ts_url] variable in the callback URL.
|
||||
// @param nb_notify Maximum bytes to read from the notification server response.
|
||||
// @return srs_success if processing succeeds, error otherwise (logged but doesn't affect HLS).
|
||||
virtual srs_error_t on_hls_notify(SrsContextId cid, std::string url, SrsRequest *req, std::string ts_url, int nb_notify) = 0;
|
||||
virtual srs_error_t on_hls_notify(SrsContextId cid, std::string url, ISrsRequest *req, std::string ts_url, int nb_notify) = 0;
|
||||
|
||||
public:
|
||||
// Origin cluster co-worker discovery hook.
|
||||
|
|
@ -125,7 +125,7 @@ public:
|
|||
// @param req The publish request information.
|
||||
// @param rtmp_urls Output parameter to receive the list of RTMP URLs for forwarding.
|
||||
// @return srs_success if backends are discovered, error otherwise.
|
||||
virtual srs_error_t on_forward_backend(std::string url, SrsRequest *req, std::vector<std::string> &rtmp_urls) = 0;
|
||||
virtual srs_error_t on_forward_backend(std::string url, ISrsRequest *req, std::vector<std::string> &rtmp_urls) = 0;
|
||||
|
||||
// Deprecated hooks.
|
||||
public:
|
||||
|
|
@ -135,7 +135,7 @@ public:
|
|||
// @param url The HTTP callback URL for client validation. If empty, hook is ignored.
|
||||
// @param req The client request information including IP, vhost, app, stream, etc.
|
||||
// @return srs_success if connection is allowed, error otherwise to reject connection.
|
||||
virtual srs_error_t on_connect(std::string url, SrsRequest *req) = 0;
|
||||
virtual srs_error_t on_connect(std::string url, ISrsRequest *req) = 0;
|
||||
|
||||
// Client disconnection notification hook.
|
||||
// Called when a client disconnects from the SRS server.
|
||||
|
|
@ -144,7 +144,7 @@ public:
|
|||
// @param req The client request information.
|
||||
// @param send_bytes Total bytes sent to the client during the session.
|
||||
// @param recv_bytes Total bytes received from the client during the session.
|
||||
virtual void on_close(std::string url, SrsRequest *req, int64_t send_bytes, int64_t recv_bytes) = 0;
|
||||
virtual void on_close(std::string url, ISrsRequest *req, int64_t send_bytes, int64_t recv_bytes) = 0;
|
||||
};
|
||||
|
||||
class SrsHttpHooks : public ISrsHttpHooks
|
||||
|
|
@ -154,18 +154,18 @@ public:
|
|||
virtual ~SrsHttpHooks();
|
||||
|
||||
public:
|
||||
srs_error_t on_connect(std::string url, SrsRequest *req);
|
||||
void on_close(std::string url, SrsRequest *req, int64_t send_bytes, int64_t recv_bytes);
|
||||
srs_error_t on_publish(std::string url, SrsRequest *req);
|
||||
void on_unpublish(std::string url, SrsRequest *req);
|
||||
srs_error_t on_play(std::string url, SrsRequest *req);
|
||||
void on_stop(std::string url, SrsRequest *req);
|
||||
srs_error_t on_dvr(SrsContextId cid, std::string url, SrsRequest *req, std::string file);
|
||||
srs_error_t on_hls(SrsContextId cid, std::string url, SrsRequest *req, std::string file, std::string ts_url,
|
||||
srs_error_t on_connect(std::string url, ISrsRequest *req);
|
||||
void on_close(std::string url, ISrsRequest *req, int64_t send_bytes, int64_t recv_bytes);
|
||||
srs_error_t on_publish(std::string url, ISrsRequest *req);
|
||||
void on_unpublish(std::string url, ISrsRequest *req);
|
||||
srs_error_t on_play(std::string url, ISrsRequest *req);
|
||||
void on_stop(std::string url, ISrsRequest *req);
|
||||
srs_error_t on_dvr(SrsContextId cid, std::string url, ISrsRequest *req, std::string file);
|
||||
srs_error_t on_hls(SrsContextId cid, std::string url, ISrsRequest *req, std::string file, std::string ts_url,
|
||||
std::string m3u8, std::string m3u8_url, int sn, srs_utime_t duration);
|
||||
srs_error_t on_hls_notify(SrsContextId cid, std::string url, SrsRequest *req, std::string ts_url, int nb_notify);
|
||||
srs_error_t on_hls_notify(SrsContextId cid, std::string url, ISrsRequest *req, std::string ts_url, int nb_notify);
|
||||
srs_error_t discover_co_workers(std::string url, std::string &host, int &port);
|
||||
srs_error_t on_forward_backend(std::string url, SrsRequest *req, std::vector<std::string> &rtmp_urls);
|
||||
srs_error_t on_forward_backend(std::string url, ISrsRequest *req, std::vector<std::string> &rtmp_urls);
|
||||
|
||||
private:
|
||||
srs_error_t do_post(SrsHttpClient *hc, std::string url, std::string req, int &code, std::string &res);
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ SrsHlsStream::~SrsHlsStream()
|
|||
srs_freep(security_);
|
||||
}
|
||||
|
||||
srs_error_t SrsHlsStream::serve_m3u8_ctx(ISrsHttpResponseWriter *w, ISrsHttpMessage *r, ISrsFileReaderFactory *factory, string fullpath, SrsRequest *req, bool *served)
|
||||
srs_error_t SrsHlsStream::serve_m3u8_ctx(ISrsHttpResponseWriter *w, ISrsHttpMessage *r, ISrsFileReaderFactory *factory, string fullpath, ISrsRequest *req, bool *served)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -144,7 +144,7 @@ void SrsHlsStream::on_serve_ts_ctx(ISrsHttpResponseWriter *w, ISrsHttpMessage *r
|
|||
SrsStatistic::instance()->kbps_add_delta(ctx, delta);
|
||||
}
|
||||
|
||||
srs_error_t SrsHlsStream::serve_new_session(ISrsHttpResponseWriter *w, ISrsHttpMessage *r, SrsRequest *req, std::string &ctx)
|
||||
srs_error_t SrsHlsStream::serve_new_session(ISrsHttpResponseWriter *w, ISrsHttpMessage *r, ISrsRequest *req, std::string &ctx)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -279,7 +279,7 @@ bool SrsHlsStream::ctx_is_exist(std::string ctx)
|
|||
return (map_ctx_info_.find(ctx) != map_ctx_info_.end());
|
||||
}
|
||||
|
||||
void SrsHlsStream::alive(std::string ctx, SrsRequest *req)
|
||||
void SrsHlsStream::alive(std::string ctx, ISrsRequest *req)
|
||||
{
|
||||
std::map<std::string, SrsHlsVirtualConn *>::iterator it = map_ctx_info_.find(ctx);
|
||||
|
||||
|
|
@ -308,7 +308,7 @@ void SrsHlsStream::alive(std::string ctx, SrsRequest *req)
|
|||
}
|
||||
}
|
||||
|
||||
srs_error_t SrsHlsStream::http_hooks_on_play(SrsRequest *req)
|
||||
srs_error_t SrsHlsStream::http_hooks_on_play(ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -341,7 +341,7 @@ srs_error_t SrsHlsStream::http_hooks_on_play(SrsRequest *req)
|
|||
return err;
|
||||
}
|
||||
|
||||
void SrsHlsStream::http_hooks_on_stop(SrsRequest *req)
|
||||
void SrsHlsStream::http_hooks_on_stop(ISrsRequest *req)
|
||||
{
|
||||
if (!_srs_config->get_vhost_http_hooks_enabled(req->vhost)) {
|
||||
return;
|
||||
|
|
@ -552,7 +552,7 @@ srs_error_t SrsVodStream::serve_m3u8_ctx(ISrsHttpResponseWriter *w, ISrsHttpMess
|
|||
SrsHttpMessage *hr = dynamic_cast<SrsHttpMessage *>(r);
|
||||
srs_assert(hr);
|
||||
|
||||
SrsUniquePtr<SrsRequest> req(hr->to_request(hr->host())->as_http());
|
||||
SrsUniquePtr<ISrsRequest> req(hr->to_request(hr->host())->as_http());
|
||||
|
||||
// discovery vhost, resolve the vhost from config
|
||||
SrsConfDirective *parsed_vhost = _srs_config->get_vhost(req->vhost);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class SrsHlsVirtualConn : public ISrsExpire
|
|||
{
|
||||
public:
|
||||
srs_utime_t request_time;
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
std::string ctx;
|
||||
bool interrupt;
|
||||
|
||||
|
|
@ -42,16 +42,16 @@ public:
|
|||
virtual ~SrsHlsStream();
|
||||
|
||||
public:
|
||||
virtual srs_error_t serve_m3u8_ctx(ISrsHttpResponseWriter *w, ISrsHttpMessage *r, ISrsFileReaderFactory *factory, std::string fullpath, SrsRequest *req, bool *served);
|
||||
virtual srs_error_t serve_m3u8_ctx(ISrsHttpResponseWriter *w, ISrsHttpMessage *r, ISrsFileReaderFactory *factory, std::string fullpath, ISrsRequest *req, bool *served);
|
||||
virtual void on_serve_ts_ctx(ISrsHttpResponseWriter *w, ISrsHttpMessage *r);
|
||||
|
||||
private:
|
||||
srs_error_t serve_new_session(ISrsHttpResponseWriter *w, ISrsHttpMessage *r, SrsRequest *req, std::string &ctx);
|
||||
srs_error_t serve_new_session(ISrsHttpResponseWriter *w, ISrsHttpMessage *r, ISrsRequest *req, std::string &ctx);
|
||||
srs_error_t serve_exists_session(ISrsHttpResponseWriter *w, ISrsHttpMessage *r, ISrsFileReaderFactory *factory, std::string fullpath);
|
||||
bool ctx_is_exist(std::string ctx);
|
||||
void alive(std::string ctx, SrsRequest *req);
|
||||
srs_error_t http_hooks_on_play(SrsRequest *req);
|
||||
void http_hooks_on_stop(SrsRequest *req);
|
||||
void alive(std::string ctx, ISrsRequest *req);
|
||||
srs_error_t http_hooks_on_play(ISrsRequest *req);
|
||||
void http_hooks_on_stop(ISrsRequest *req);
|
||||
bool is_interrupt(std::string id);
|
||||
// interface ISrsFastTimer
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ using namespace std;
|
|||
#include <srs_protocol_stream.hpp>
|
||||
#include <srs_protocol_utility.hpp>
|
||||
|
||||
SrsBufferCache::SrsBufferCache(SrsServer *s, SrsRequest *r)
|
||||
SrsBufferCache::SrsBufferCache(SrsServer *s, ISrsRequest *r)
|
||||
{
|
||||
req = r->copy()->as_http();
|
||||
queue = new SrsMessageQueue(true);
|
||||
|
|
@ -59,7 +59,7 @@ SrsBufferCache::~SrsBufferCache()
|
|||
srs_freep(req);
|
||||
}
|
||||
|
||||
srs_error_t SrsBufferCache::update_auth(SrsRequest *r)
|
||||
srs_error_t SrsBufferCache::update_auth(ISrsRequest *r)
|
||||
{
|
||||
srs_freep(req);
|
||||
req = r->copy();
|
||||
|
|
@ -133,7 +133,7 @@ srs_error_t SrsBufferCache::cycle()
|
|||
srs_error_t err = srs_success;
|
||||
|
||||
SrsSharedPtr<SrsLiveSource> live_source;
|
||||
if ((err = _srs_sources->fetch_or_create(req, server_, live_source)) != srs_success) {
|
||||
if ((err = _srs_sources->fetch_or_create(req, live_source)) != srs_success) {
|
||||
return srs_error_wrap(err, "source create");
|
||||
}
|
||||
srs_assert(live_source.get() != NULL);
|
||||
|
|
@ -596,7 +596,7 @@ srs_error_t SrsBufferWriter::writev(const iovec *iov, int iovcnt, ssize_t *pnwri
|
|||
return writer->writev(iov, iovcnt, pnwrite);
|
||||
}
|
||||
|
||||
SrsLiveStream::SrsLiveStream(SrsServer *s, SrsRequest *r, SrsBufferCache *c)
|
||||
SrsLiveStream::SrsLiveStream(SrsServer *s, ISrsRequest *r, SrsBufferCache *c)
|
||||
{
|
||||
cache = c;
|
||||
req = r->copy()->as_http();
|
||||
|
|
@ -613,7 +613,7 @@ SrsLiveStream::~SrsLiveStream()
|
|||
srs_assert(viewers_.empty());
|
||||
}
|
||||
|
||||
srs_error_t SrsLiveStream::update_auth(SrsRequest *r)
|
||||
srs_error_t SrsLiveStream::update_auth(ISrsRequest *r)
|
||||
{
|
||||
srs_freep(req);
|
||||
req = r->copy()->as_http();
|
||||
|
|
@ -684,7 +684,7 @@ srs_error_t SrsLiveStream::serve_http_impl(ISrsHttpResponseWriter *w, ISrsHttpMe
|
|||
|
||||
// Always try to create the source, because http handler won't create it.
|
||||
SrsSharedPtr<SrsLiveSource> live_source;
|
||||
if ((err = _srs_sources->fetch_or_create(req, server_, live_source)) != srs_success) {
|
||||
if ((err = _srs_sources->fetch_or_create(req, live_source)) != srs_success) {
|
||||
return srs_error_wrap(err, "source create");
|
||||
}
|
||||
srs_assert(live_source.get() != NULL);
|
||||
|
|
@ -887,7 +887,7 @@ srs_error_t SrsLiveStream::http_hooks_on_play(ISrsHttpMessage *r)
|
|||
|
||||
// Create request to report for the specified connection.
|
||||
SrsHttpMessage *hr = dynamic_cast<SrsHttpMessage *>(r);
|
||||
SrsUniquePtr<SrsRequest> nreq(hr->to_request(req->vhost));
|
||||
SrsUniquePtr<ISrsRequest> nreq(hr->to_request(req->vhost));
|
||||
|
||||
// the http hooks will cause context switch,
|
||||
// so we must copy all hooks for the on_connect may freed.
|
||||
|
|
@ -922,7 +922,7 @@ void SrsLiveStream::http_hooks_on_stop(ISrsHttpMessage *r)
|
|||
|
||||
// Create request to report for the specified connection.
|
||||
SrsHttpMessage *hr = dynamic_cast<SrsHttpMessage *>(r);
|
||||
SrsUniquePtr<SrsRequest> nreq(hr->to_request(req->vhost));
|
||||
SrsUniquePtr<ISrsRequest> nreq(hr->to_request(req->vhost));
|
||||
|
||||
// the http hooks will cause context switch,
|
||||
// so we must copy all hooks for the on_connect may freed.
|
||||
|
|
@ -1067,7 +1067,7 @@ srs_error_t SrsHttpStreamServer::initialize()
|
|||
}
|
||||
|
||||
// TODO: FIXME: rename for HTTP FLV mount.
|
||||
srs_error_t SrsHttpStreamServer::http_mount(SrsRequest *r)
|
||||
srs_error_t SrsHttpStreamServer::http_mount(ISrsRequest *r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -1144,7 +1144,7 @@ srs_error_t SrsHttpStreamServer::http_mount(SrsRequest *r)
|
|||
return err;
|
||||
}
|
||||
|
||||
void SrsHttpStreamServer::http_unmount(SrsRequest *r)
|
||||
void SrsHttpStreamServer::http_unmount(ISrsRequest *r)
|
||||
{
|
||||
std::string sid = r->get_stream_url();
|
||||
|
||||
|
|
@ -1245,7 +1245,7 @@ srs_error_t SrsHttpStreamServer::hijack(ISrsHttpMessage *request, ISrsHttpHandle
|
|||
srs_assert(hreq);
|
||||
|
||||
// hijack for entry.
|
||||
SrsUniquePtr<SrsRequest> r(hreq->to_request(vhost->arg0()));
|
||||
SrsUniquePtr<ISrsRequest> r(hreq->to_request(vhost->arg0()));
|
||||
|
||||
std::string sid = r->get_stream_url();
|
||||
// check whether the http remux is enabled,
|
||||
|
|
|
|||
|
|
@ -29,13 +29,13 @@ private:
|
|||
|
||||
private:
|
||||
SrsMessageQueue *queue;
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
SrsCoroutine *trd;
|
||||
|
||||
public:
|
||||
SrsBufferCache(SrsServer *s, SrsRequest *r);
|
||||
SrsBufferCache(SrsServer *s, ISrsRequest *r);
|
||||
virtual ~SrsBufferCache();
|
||||
virtual srs_error_t update_auth(SrsRequest *r);
|
||||
virtual srs_error_t update_auth(ISrsRequest *r);
|
||||
|
||||
public:
|
||||
virtual srs_error_t start();
|
||||
|
|
@ -209,7 +209,7 @@ public:
|
|||
class SrsLiveStream : public ISrsHttpHandler, public ISrsExpire
|
||||
{
|
||||
private:
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
SrsBufferCache *cache;
|
||||
SrsSecurity *security_;
|
||||
SrsServer *server_;
|
||||
|
|
@ -219,9 +219,9 @@ private:
|
|||
std::vector<ISrsExpire *> viewers_;
|
||||
|
||||
public:
|
||||
SrsLiveStream(SrsServer *s, SrsRequest *r, SrsBufferCache *c);
|
||||
SrsLiveStream(SrsServer *s, ISrsRequest *r, SrsBufferCache *c);
|
||||
virtual ~SrsLiveStream();
|
||||
virtual srs_error_t update_auth(SrsRequest *r);
|
||||
virtual srs_error_t update_auth(ISrsRequest *r);
|
||||
|
||||
public:
|
||||
virtual srs_error_t serve_http(ISrsHttpResponseWriter *w, ISrsHttpMessage *r);
|
||||
|
|
@ -252,7 +252,7 @@ private:
|
|||
|
||||
public:
|
||||
// We will free the request.
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
|
||||
public:
|
||||
// For template, the mount contains variables.
|
||||
|
|
@ -298,8 +298,8 @@ public:
|
|||
|
||||
public:
|
||||
// HTTP flv/ts/mp3/aac stream
|
||||
virtual srs_error_t http_mount(SrsRequest *r);
|
||||
virtual void http_unmount(SrsRequest *r);
|
||||
virtual srs_error_t http_mount(ISrsRequest *r);
|
||||
virtual void http_unmount(ISrsRequest *r);
|
||||
// Interface ISrsHttpMatchHijacker
|
||||
public:
|
||||
virtual srs_error_t hijack(ISrsHttpMessage *request, ISrsHttpHandler **ph);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class SrsConfDirective;
|
|||
class SrsSimpleStream;
|
||||
class SrsRtmpClient;
|
||||
class SrsStSocket;
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsRawH264Stream;
|
||||
class SrsSharedPtrMessage;
|
||||
class SrsRawAacStream;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ SrsNgExec::~SrsNgExec()
|
|||
srs_freep(pprint);
|
||||
}
|
||||
|
||||
srs_error_t SrsNgExec::on_publish(SrsRequest *req)
|
||||
srs_error_t SrsNgExec::on_publish(ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -120,7 +120,7 @@ srs_error_t SrsNgExec::do_cycle()
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsNgExec::parse_exec_publish(SrsRequest *req)
|
||||
srs_error_t SrsNgExec::parse_exec_publish(ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -193,7 +193,7 @@ void SrsNgExec::show_exec_log_message()
|
|||
}
|
||||
}
|
||||
|
||||
string SrsNgExec::parse(SrsRequest *req, string tmpl)
|
||||
string SrsNgExec::parse(ISrsRequest *req, string tmpl)
|
||||
{
|
||||
string output = tmpl;
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include <srs_app_st.hpp>
|
||||
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsPithyPrint;
|
||||
class SrsProcess;
|
||||
|
||||
|
|
@ -34,7 +34,7 @@ public:
|
|||
virtual ~SrsNgExec();
|
||||
|
||||
public:
|
||||
virtual srs_error_t on_publish(SrsRequest *req);
|
||||
virtual srs_error_t on_publish(ISrsRequest *req);
|
||||
virtual void on_unpublish();
|
||||
// Interface ISrsReusableThreadHandler.
|
||||
public:
|
||||
|
|
@ -44,10 +44,10 @@ private:
|
|||
virtual srs_error_t do_cycle();
|
||||
|
||||
private:
|
||||
virtual srs_error_t parse_exec_publish(SrsRequest *req);
|
||||
virtual srs_error_t parse_exec_publish(ISrsRequest *req);
|
||||
virtual void clear_exec_publish();
|
||||
virtual void show_exec_log_message();
|
||||
virtual std::string parse(SrsRequest *req, std::string tmpl);
|
||||
virtual std::string parse(ISrsRequest *req, std::string tmpl);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ void SrsQueueRecvThread::on_stop()
|
|||
rtmp->set_auto_response(true);
|
||||
}
|
||||
|
||||
SrsPublishRecvThread::SrsPublishRecvThread(SrsRtmpServer *rtmp_sdk, SrsRequest *_req,
|
||||
SrsPublishRecvThread::SrsPublishRecvThread(SrsRtmpServer *rtmp_sdk, ISrsRequest *_req,
|
||||
int mr_sock_fd, srs_utime_t tm, SrsRtmpConn *conn, SrsSharedPtr<SrsLiveSource> source, SrsContextId parent_cid)
|
||||
: trd(this, rtmp_sdk, tm, parent_cid)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class SrsRtmpServer;
|
|||
class SrsCommonMessage;
|
||||
class SrsRtmpConn;
|
||||
class SrsLiveSource;
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsLiveConsumer;
|
||||
class SrsHttpConn;
|
||||
class SrsHttpxConn;
|
||||
|
|
@ -141,7 +141,7 @@ private:
|
|||
uint32_t nn_msgs_for_yield_;
|
||||
SrsRecvThread trd;
|
||||
SrsRtmpServer *rtmp;
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
// The msgs already got.
|
||||
int64_t _nb_msgs;
|
||||
// The video frames we got.
|
||||
|
|
@ -165,7 +165,7 @@ private:
|
|||
SrsContextId ncid;
|
||||
|
||||
public:
|
||||
SrsPublishRecvThread(SrsRtmpServer *rtmp_sdk, SrsRequest *_req,
|
||||
SrsPublishRecvThread(SrsRtmpServer *rtmp_sdk, ISrsRequest *_req,
|
||||
int mr_sock_fd, srs_utime_t tm, SrsRtmpConn *conn, SrsSharedPtr<SrsLiveSource> source, SrsContextId parent_cid);
|
||||
virtual ~SrsPublishRecvThread();
|
||||
|
||||
|
|
|
|||
|
|
@ -292,7 +292,7 @@ srs_error_t SrsGoApiRtcPlay::check_remote_sdp(const SrsSdp &remote_sdp)
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsGoApiRtcPlay::http_hooks_on_play(SrsRequest *req)
|
||||
srs_error_t SrsGoApiRtcPlay::http_hooks_on_play(ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -567,7 +567,7 @@ srs_error_t SrsGoApiRtcPublish::check_remote_sdp(const SrsSdp &remote_sdp)
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsGoApiRtcPublish::http_hooks_on_publish(SrsRequest *req)
|
||||
srs_error_t SrsGoApiRtcPublish::http_hooks_on_publish(ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include <srs_protocol_http_stack.hpp>
|
||||
|
||||
class SrsRtcServer;
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsSdp;
|
||||
class SrsRtcUserConfig;
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ private:
|
|||
srs_error_t check_remote_sdp(const SrsSdp &remote_sdp);
|
||||
|
||||
private:
|
||||
virtual srs_error_t http_hooks_on_play(SrsRequest *req);
|
||||
virtual srs_error_t http_hooks_on_play(ISrsRequest *req);
|
||||
};
|
||||
|
||||
class SrsGoApiRtcPublish : public ISrsHttpHandler
|
||||
|
|
@ -65,7 +65,7 @@ private:
|
|||
srs_error_t check_remote_sdp(const SrsSdp &remote_sdp);
|
||||
|
||||
private:
|
||||
virtual srs_error_t http_hooks_on_publish(SrsRequest *req);
|
||||
virtual srs_error_t http_hooks_on_publish(ISrsRequest *req);
|
||||
};
|
||||
|
||||
// See https://datatracker.ietf.org/doc/draft-ietf-wish-whip/
|
||||
|
|
|
|||
|
|
@ -364,7 +364,7 @@ srs_error_t SrsRtcPLIWorker::cycle()
|
|||
return err;
|
||||
}
|
||||
|
||||
SrsRtcAsyncCallOnStop::SrsRtcAsyncCallOnStop(SrsContextId c, SrsRequest *r)
|
||||
SrsRtcAsyncCallOnStop::SrsRtcAsyncCallOnStop(SrsContextId c, ISrsRequest *r)
|
||||
{
|
||||
cid = c;
|
||||
req = r->copy();
|
||||
|
|
@ -471,7 +471,7 @@ SrsRtcPlayStream::~SrsRtcPlayStream()
|
|||
stat->on_disconnect(cid_.c_str(), srs_success);
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcPlayStream::initialize(SrsRequest *req, std::map<uint32_t, SrsRtcTrackDescription *> sub_relations)
|
||||
srs_error_t SrsRtcPlayStream::initialize(ISrsRequest *req, std::map<uint32_t, SrsRtcTrackDescription *> sub_relations)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -1022,7 +1022,7 @@ srs_error_t SrsRtcPublishTwccTimer::on_timer(srs_utime_t interval)
|
|||
return err;
|
||||
}
|
||||
|
||||
SrsRtcAsyncCallOnUnpublish::SrsRtcAsyncCallOnUnpublish(SrsContextId c, SrsRequest *r)
|
||||
SrsRtcAsyncCallOnUnpublish::SrsRtcAsyncCallOnUnpublish(SrsContextId c, ISrsRequest *r)
|
||||
{
|
||||
cid = c;
|
||||
req = r->copy();
|
||||
|
|
@ -1134,7 +1134,7 @@ SrsRtcPublishStream::~SrsRtcPublishStream()
|
|||
stat->on_disconnect(cid_.c_str(), srs_success);
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcPublishStream::initialize(SrsRequest *r, SrsRtcSourceDescription *stream_desc)
|
||||
srs_error_t SrsRtcPublishStream::initialize(ISrsRequest *r, SrsRtcSourceDescription *stream_desc)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -1226,7 +1226,7 @@ srs_error_t SrsRtcPublishStream::initialize(SrsRequest *r, SrsRtcSourceDescripti
|
|||
#if defined(SRS_FFMPEG_FIT)
|
||||
bool rtc_to_rtmp = _srs_config->get_rtc_to_rtmp(req_->vhost);
|
||||
if (rtc_to_rtmp) {
|
||||
if ((err = _srs_sources->fetch_or_create(r, _srs_hybrid->srs()->instance(), live_source)) != srs_success) {
|
||||
if ((err = _srs_sources->fetch_or_create(r, live_source)) != srs_success) {
|
||||
return srs_error_wrap(err, "create source");
|
||||
}
|
||||
|
||||
|
|
@ -1937,7 +1937,7 @@ srs_error_t SrsRtcConnection::add_publisher(SrsRtcUserConfig *ruc, SrsSdp &local
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = ruc->req_;
|
||||
ISrsRequest *req = ruc->req_;
|
||||
|
||||
SrsUniquePtr<SrsRtcSourceDescription> stream_desc(new SrsRtcSourceDescription());
|
||||
|
||||
|
|
@ -1978,7 +1978,7 @@ srs_error_t SrsRtcConnection::add_player(SrsRtcUserConfig *ruc, SrsSdp &local_sd
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = ruc->req_;
|
||||
ISrsRequest *req = ruc->req_;
|
||||
|
||||
std::map<uint32_t, SrsRtcTrackDescription *> play_sub_relations;
|
||||
if ((err = negotiate_play_capability(ruc, play_sub_relations)) != srs_success) {
|
||||
|
|
@ -2016,7 +2016,7 @@ srs_error_t SrsRtcConnection::add_player(SrsRtcUserConfig *ruc, SrsSdp &local_sd
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcConnection::initialize(SrsRequest *r, bool dtls, bool srtp, string username)
|
||||
srs_error_t SrsRtcConnection::initialize(ISrsRequest *r, bool dtls, bool srtp, string username)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -2654,7 +2654,7 @@ srs_error_t SrsRtcConnection::negotiate_publish_capability(SrsRtcUserConfig *ruc
|
|||
return srs_error_new(ERROR_RTC_SDP_EXCHANGE, "stream description is NULL");
|
||||
}
|
||||
|
||||
SrsRequest *req = ruc->req_;
|
||||
ISrsRequest *req = ruc->req_;
|
||||
const SrsSdp &remote_sdp = ruc->remote_sdp_;
|
||||
|
||||
bool nack_enabled = _srs_config->get_rtc_nack_enabled(req->vhost);
|
||||
|
|
@ -2947,7 +2947,7 @@ srs_error_t SrsRtcConnection::negotiate_publish_capability(SrsRtcUserConfig *ruc
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcConnection::generate_publish_local_sdp(SrsRequest *req, SrsSdp &local_sdp, SrsRtcSourceDescription *stream_desc, bool unified_plan, bool audio_before_video)
|
||||
srs_error_t SrsRtcConnection::generate_publish_local_sdp(ISrsRequest *req, SrsSdp &local_sdp, SrsRtcSourceDescription *stream_desc, bool unified_plan, bool audio_before_video)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -3086,7 +3086,7 @@ srs_error_t SrsRtcConnection::negotiate_play_capability(SrsRtcUserConfig *ruc, s
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = ruc->req_;
|
||||
ISrsRequest *req = ruc->req_;
|
||||
const SrsSdp &remote_sdp = ruc->remote_sdp_;
|
||||
|
||||
bool nack_enabled = _srs_config->get_rtc_nack_enabled(req->vhost);
|
||||
|
|
@ -3325,7 +3325,7 @@ void video_track_generate_play_offer(SrsRtcTrackDescription *track, string mid,
|
|||
}
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcConnection::generate_play_local_sdp(SrsRequest *req, SrsSdp &local_sdp, SrsRtcSourceDescription *stream_desc, bool unified_plan, bool audio_before_video)
|
||||
srs_error_t SrsRtcConnection::generate_play_local_sdp(ISrsRequest *req, SrsSdp &local_sdp, SrsRtcSourceDescription *stream_desc, bool unified_plan, bool audio_before_video)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -3479,7 +3479,7 @@ srs_error_t SrsRtcConnection::generate_play_local_sdp_for_video(SrsSdp &local_sd
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcConnection::create_player(SrsRequest *req, std::map<uint32_t, SrsRtcTrackDescription *> sub_relations)
|
||||
srs_error_t SrsRtcConnection::create_player(ISrsRequest *req, std::map<uint32_t, SrsRtcTrackDescription *> sub_relations)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -3545,7 +3545,7 @@ srs_error_t SrsRtcConnection::create_player(SrsRequest *req, std::map<uint32_t,
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcConnection::create_publisher(SrsRequest *req, SrsRtcSourceDescription *stream_desc)
|
||||
srs_error_t SrsRtcConnection::create_publisher(ISrsRequest *req, SrsRtcSourceDescription *stream_desc)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
|
|||
|
|
@ -211,10 +211,10 @@ class SrsRtcAsyncCallOnStop : public ISrsAsyncCallTask
|
|||
{
|
||||
private:
|
||||
SrsContextId cid;
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
|
||||
public:
|
||||
SrsRtcAsyncCallOnStop(SrsContextId c, SrsRequest *r);
|
||||
SrsRtcAsyncCallOnStop(SrsContextId c, ISrsRequest *r);
|
||||
virtual ~SrsRtcAsyncCallOnStop();
|
||||
|
||||
public:
|
||||
|
|
@ -232,7 +232,7 @@ private:
|
|||
SrsRtcPLIWorker *pli_worker_;
|
||||
|
||||
private:
|
||||
SrsRequest *req_;
|
||||
ISrsRequest *req_;
|
||||
SrsSharedPtr<SrsRtcSource> source_;
|
||||
// key: publish_ssrc, value: send track to process rtp/rtcp
|
||||
std::map<uint32_t, SrsRtcAudioSendTrack *> audio_tracks_;
|
||||
|
|
@ -266,7 +266,7 @@ public:
|
|||
virtual ~SrsRtcPlayStream();
|
||||
|
||||
public:
|
||||
srs_error_t initialize(SrsRequest *request, std::map<uint32_t, SrsRtcTrackDescription *> sub_relations);
|
||||
srs_error_t initialize(ISrsRequest *request, std::map<uint32_t, SrsRtcTrackDescription *> sub_relations);
|
||||
// Interface ISrsRtcSourceChangeCallback
|
||||
public:
|
||||
void on_stream_change(SrsRtcSourceDescription *desc);
|
||||
|
|
@ -337,10 +337,10 @@ class SrsRtcAsyncCallOnUnpublish : public ISrsAsyncCallTask
|
|||
{
|
||||
private:
|
||||
SrsContextId cid;
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
|
||||
public:
|
||||
SrsRtcAsyncCallOnUnpublish(SrsContextId c, SrsRequest *r);
|
||||
SrsRtcAsyncCallOnUnpublish(SrsContextId c, ISrsRequest *r);
|
||||
virtual ~SrsRtcAsyncCallOnUnpublish();
|
||||
|
||||
public:
|
||||
|
|
@ -376,7 +376,7 @@ private:
|
|||
SrsErrorPithyPrint *pli_epp;
|
||||
|
||||
private:
|
||||
SrsRequest *req_;
|
||||
ISrsRequest *req_;
|
||||
SrsSharedPtr<SrsRtcSource> source_;
|
||||
// Simulators.
|
||||
int nn_simulate_nack_drop;
|
||||
|
|
@ -399,7 +399,7 @@ public:
|
|||
virtual ~SrsRtcPublishStream();
|
||||
|
||||
public:
|
||||
srs_error_t initialize(SrsRequest *req, SrsRtcSourceDescription *stream_desc);
|
||||
srs_error_t initialize(ISrsRequest *req, SrsRtcSourceDescription *stream_desc);
|
||||
srs_error_t start();
|
||||
// Directly set the status of track, generally for init to set the default value.
|
||||
void set_all_tracks_status(bool status);
|
||||
|
|
@ -516,7 +516,7 @@ private:
|
|||
private:
|
||||
// For each RTC session, we use a specified cid for debugging logs.
|
||||
SrsContextId cid_;
|
||||
SrsRequest *req_;
|
||||
ISrsRequest *req_;
|
||||
SrsSdp remote_sdp;
|
||||
SrsSdp local_sdp;
|
||||
|
||||
|
|
@ -572,7 +572,7 @@ public:
|
|||
|
||||
public:
|
||||
// Before initialize, user must set the local SDP, which is used to inititlize DTLS.
|
||||
srs_error_t initialize(SrsRequest *r, bool dtls, bool srtp, std::string username);
|
||||
srs_error_t initialize(ISrsRequest *r, bool dtls, bool srtp, std::string username);
|
||||
srs_error_t on_rtp_cipher(char *data, int nb_data);
|
||||
srs_error_t on_rtp_plaintext(char *data, int nb_data);
|
||||
|
||||
|
|
@ -623,17 +623,17 @@ public:
|
|||
private:
|
||||
// publish media capabilitiy negotiate
|
||||
srs_error_t negotiate_publish_capability(SrsRtcUserConfig *ruc, SrsRtcSourceDescription *stream_desc);
|
||||
srs_error_t generate_publish_local_sdp(SrsRequest *req, SrsSdp &local_sdp, SrsRtcSourceDescription *stream_desc, bool unified_plan, bool audio_before_video);
|
||||
srs_error_t generate_publish_local_sdp(ISrsRequest *req, SrsSdp &local_sdp, SrsRtcSourceDescription *stream_desc, bool unified_plan, bool audio_before_video);
|
||||
srs_error_t generate_publish_local_sdp_for_audio(SrsSdp &local_sdp, SrsRtcSourceDescription *stream_desc);
|
||||
srs_error_t generate_publish_local_sdp_for_video(SrsSdp &local_sdp, SrsRtcSourceDescription *stream_desc, bool unified_plan);
|
||||
// play media capabilitiy negotiate
|
||||
// TODO: Use StreamDescription to negotiate and remove first negotiate_play_capability function
|
||||
srs_error_t negotiate_play_capability(SrsRtcUserConfig *ruc, std::map<uint32_t, SrsRtcTrackDescription *> &sub_relations);
|
||||
srs_error_t generate_play_local_sdp(SrsRequest *req, SrsSdp &local_sdp, SrsRtcSourceDescription *stream_desc, bool unified_plan, bool audio_before_video);
|
||||
srs_error_t generate_play_local_sdp(ISrsRequest *req, SrsSdp &local_sdp, SrsRtcSourceDescription *stream_desc, bool unified_plan, bool audio_before_video);
|
||||
srs_error_t generate_play_local_sdp_for_audio(SrsSdp &local_sdp, SrsRtcSourceDescription *stream_desc, std::string cname);
|
||||
srs_error_t generate_play_local_sdp_for_video(SrsSdp &local_sdp, SrsRtcSourceDescription *stream_desc, bool unified_plan, std::string cname);
|
||||
srs_error_t create_player(SrsRequest *request, std::map<uint32_t, SrsRtcTrackDescription *> sub_relations);
|
||||
srs_error_t create_publisher(SrsRequest *request, SrsRtcSourceDescription *stream_desc);
|
||||
srs_error_t create_player(ISrsRequest *request, std::map<uint32_t, SrsRtcTrackDescription *> sub_relations);
|
||||
srs_error_t create_publisher(ISrsRequest *request, SrsRtcSourceDescription *stream_desc);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
#include <srs_app_st.hpp>
|
||||
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
|
||||
class SrsDtlsCertificate
|
||||
{
|
||||
|
|
|
|||
|
|
@ -500,7 +500,7 @@ srs_error_t SrsRtcServer::create_session(SrsRtcUserConfig *ruc, SrsSdp &local_sd
|
|||
|
||||
SrsContextId cid = _srs_context->get_id();
|
||||
|
||||
SrsRequest *req = ruc->req_;
|
||||
ISrsRequest *req = ruc->req_;
|
||||
|
||||
SrsSharedPtr<SrsRtcSource> source;
|
||||
if ((err = _srs_rtc_sources->fetch_or_create(req, source)) != srs_success) {
|
||||
|
|
@ -527,7 +527,7 @@ srs_error_t SrsRtcServer::do_create_session(SrsRtcUserConfig *ruc, SrsSdp &local
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = ruc->req_;
|
||||
ISrsRequest *req = ruc->req_;
|
||||
|
||||
// first add publisher/player for negotiate sdp media info
|
||||
if (ruc->publish_) {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
class SrsRtcServer;
|
||||
class SrsHourGlass;
|
||||
class SrsRtcConnection;
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsSdp;
|
||||
class SrsRtcSource;
|
||||
class SrsResourceManager;
|
||||
|
|
@ -68,7 +68,7 @@ public:
|
|||
std::string token_;
|
||||
|
||||
// Generated data.
|
||||
SrsRequest *req_;
|
||||
ISrsRequest *req_;
|
||||
bool publish_;
|
||||
bool dtls_;
|
||||
bool srtp_;
|
||||
|
|
|
|||
|
|
@ -290,43 +290,49 @@ srs_error_t SrsRtcSourceManager::notify(int event, srs_utime_t interval, srs_uti
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcSourceManager::fetch_or_create(SrsRequest *r, SrsSharedPtr<SrsRtcSource> &pps)
|
||||
srs_error_t SrsRtcSourceManager::fetch_or_create(ISrsRequest *r, SrsSharedPtr<SrsRtcSource> &pps)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// Use lock to protect coroutine switch.
|
||||
// @bug https://github.com/ossrs/srs/issues/1230
|
||||
SrsLocker(lock);
|
||||
bool created = false;
|
||||
// Should never invoke any function during the locking.
|
||||
if (true) {
|
||||
// Use lock to protect coroutine switch.
|
||||
// @bug https://github.com/ossrs/srs/issues/1230
|
||||
SrsLocker(lock);
|
||||
|
||||
string stream_url = r->get_stream_url();
|
||||
std::map<std::string, SrsSharedPtr<SrsRtcSource> >::iterator it = pool.find(stream_url);
|
||||
string stream_url = r->get_stream_url();
|
||||
std::map<std::string, SrsSharedPtr<SrsRtcSource> >::iterator it = pool.find(stream_url);
|
||||
|
||||
if (it != pool.end()) {
|
||||
SrsSharedPtr<SrsRtcSource> source = it->second;
|
||||
if (it != pool.end()) {
|
||||
SrsSharedPtr<SrsRtcSource> source = it->second;
|
||||
pps = source;
|
||||
} else {
|
||||
SrsSharedPtr<SrsRtcSource> source = SrsSharedPtr<SrsRtcSource>(new SrsRtcSource());
|
||||
srs_trace("new rtc source, stream_url=%s", stream_url.c_str());
|
||||
pps = source;
|
||||
|
||||
// we always update the request of resource,
|
||||
// for origin auth is on, the token in request maybe invalid,
|
||||
// and we only need to update the token of request, it's simple.
|
||||
source->update_auth(r);
|
||||
pps = source;
|
||||
|
||||
return err;
|
||||
pool[stream_url] = source;
|
||||
created = true;
|
||||
}
|
||||
}
|
||||
|
||||
SrsSharedPtr<SrsRtcSource> source = SrsSharedPtr<SrsRtcSource>(new SrsRtcSource());
|
||||
srs_trace("new rtc source, stream_url=%s", stream_url.c_str());
|
||||
|
||||
if ((err = source->initialize(r)) != srs_success) {
|
||||
// Initialize source.
|
||||
if (created && (err = pps->initialize(r)) != srs_success) {
|
||||
return srs_error_wrap(err, "init source %s", r->get_stream_url().c_str());
|
||||
}
|
||||
|
||||
pool[stream_url] = source;
|
||||
pps = source;
|
||||
// we always update the request of resource,
|
||||
// for origin auth is on, the token in request maybe invalid,
|
||||
// and we only need to update the token of request, it's simple.
|
||||
if (!created) {
|
||||
pps->update_auth(r);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
SrsSharedPtr<SrsRtcSource> SrsRtcSourceManager::fetch(SrsRequest *r)
|
||||
SrsSharedPtr<SrsRtcSource> SrsRtcSourceManager::fetch(ISrsRequest *r)
|
||||
{
|
||||
// Use lock to protect coroutine switch.
|
||||
// @bug https://github.com/ossrs/srs/issues/1230
|
||||
|
|
@ -399,7 +405,19 @@ SrsRtcSource::~SrsRtcSource()
|
|||
srs_trace("free rtc source id=[%s]", cid.c_str());
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcSource::initialize(SrsRequest *r)
|
||||
// CRITICAL: This method is called AFTER the source has been added to the source pool
|
||||
// in the fetch_or_create pattern (see PR 4449).
|
||||
//
|
||||
// IMPORTANT: All field initialization in this method MUST NOT cause coroutine context switches
|
||||
// before completing the basic field setup.
|
||||
//
|
||||
// If context switches occur before all fields are properly initialized, other coroutines
|
||||
// accessing this source from the pool may encounter uninitialized state, leading to crashes
|
||||
// or undefined behavior.
|
||||
//
|
||||
// This prevents the race condition where multiple coroutines could create duplicate sources
|
||||
// for the same stream when context switches occurred during initialization.
|
||||
srs_error_t SrsRtcSource::initialize(ISrsRequest *r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -499,7 +517,7 @@ void SrsRtcSource::init_for_play_before_publishing()
|
|||
set_stream_desc(stream_desc.get());
|
||||
}
|
||||
|
||||
void SrsRtcSource::update_auth(SrsRequest *r)
|
||||
void SrsRtcSource::update_auth(ISrsRequest *r)
|
||||
{
|
||||
req->update_auth(r);
|
||||
}
|
||||
|
|
@ -937,7 +955,7 @@ srs_error_t SrsRtcRtpBuilder::initialize_video_track(SrsVideoCodecId codec)
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcRtpBuilder::initialize(SrsRequest *r)
|
||||
srs_error_t SrsRtcRtpBuilder::initialize(ISrsRequest *r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -1733,7 +1751,7 @@ SrsRtcFrameBuilder::~SrsRtcFrameBuilder()
|
|||
srs_freep(obs_whip_pps_);
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcFrameBuilder::initialize(SrsRequest *r, SrsAudioCodecId audio_codec, SrsVideoCodecId video_codec)
|
||||
srs_error_t SrsRtcFrameBuilder::initialize(ISrsRequest *r, SrsAudioCodecId audio_codec, SrsVideoCodecId video_codec)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#include <srs_protocol_format.hpp>
|
||||
#include <srs_protocol_st.hpp>
|
||||
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsMetaCache;
|
||||
class SrsSharedPtrMessage;
|
||||
class SrsCommonMessage;
|
||||
|
|
@ -150,11 +150,11 @@ public:
|
|||
// create source when fetch from cache failed.
|
||||
// @param r the client request.
|
||||
// @param pps the matched source, if success never be NULL.
|
||||
virtual srs_error_t fetch_or_create(SrsRequest *r, SrsSharedPtr<SrsRtcSource> &pps);
|
||||
virtual srs_error_t fetch_or_create(ISrsRequest *r, SrsSharedPtr<SrsRtcSource> &pps);
|
||||
|
||||
public:
|
||||
// Get the exists source, NULL when not exists.
|
||||
virtual SrsSharedPtr<SrsRtcSource> fetch(SrsRequest *r);
|
||||
virtual SrsSharedPtr<SrsRtcSource> fetch(ISrsRequest *r);
|
||||
};
|
||||
|
||||
// Global singleton instance.
|
||||
|
|
@ -198,7 +198,7 @@ private:
|
|||
SrsContextId _source_id;
|
||||
// previous source id.
|
||||
SrsContextId _pre_source_id;
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
ISrsRtcPublishStream *publish_stream_;
|
||||
// Steam description for this steam.
|
||||
SrsRtcSourceDescription *stream_desc_;
|
||||
|
|
@ -235,7 +235,7 @@ public:
|
|||
virtual ~SrsRtcSource();
|
||||
|
||||
public:
|
||||
virtual srs_error_t initialize(SrsRequest *r);
|
||||
virtual srs_error_t initialize(ISrsRequest *r);
|
||||
|
||||
public:
|
||||
// Whether stream is dead, which is no publisher or player.
|
||||
|
|
@ -246,7 +246,7 @@ private:
|
|||
|
||||
public:
|
||||
// Update the authentication information in request.
|
||||
virtual void update_auth(SrsRequest *r);
|
||||
virtual void update_auth(ISrsRequest *r);
|
||||
|
||||
private:
|
||||
// The stream source changed.
|
||||
|
|
@ -306,7 +306,7 @@ private:
|
|||
class SrsRtcRtpBuilder
|
||||
{
|
||||
private:
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
SrsFrameToRtcBridge *bridge_;
|
||||
// The format, codec information.
|
||||
SrsRtmpFormat *format;
|
||||
|
|
@ -343,7 +343,7 @@ private:
|
|||
srs_error_t initialize_video_track(SrsVideoCodecId codec);
|
||||
|
||||
public:
|
||||
virtual srs_error_t initialize(SrsRequest *r);
|
||||
virtual srs_error_t initialize(ISrsRequest *r);
|
||||
virtual srs_error_t on_publish();
|
||||
virtual void on_unpublish();
|
||||
virtual srs_error_t on_frame(SrsSharedPtrMessage *frame);
|
||||
|
|
@ -490,7 +490,7 @@ public:
|
|||
virtual ~SrsRtcFrameBuilder();
|
||||
|
||||
public:
|
||||
srs_error_t initialize(SrsRequest *r, SrsAudioCodecId audio_codec, SrsVideoCodecId video_codec);
|
||||
srs_error_t initialize(ISrsRequest *r, SrsAudioCodecId audio_codec, SrsVideoCodecId video_codec);
|
||||
virtual srs_error_t on_publish();
|
||||
virtual void on_unpublish();
|
||||
virtual srs_error_t on_rtp(SrsRtpPacket *pkt);
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ srs_error_t SrsRtmpConn::do_cycle()
|
|||
span_connect_ = _srs_apm->span("connect")->as_child(span_main_);
|
||||
#endif
|
||||
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
if ((err = rtmp->connect_app(req)) != srs_success) {
|
||||
return srs_error_wrap(err, "rtmp connect tcUrl");
|
||||
}
|
||||
|
|
@ -368,7 +368,7 @@ srs_error_t SrsRtmpConn::on_reload_vhost_removed(string vhost)
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
|
||||
if (req->vhost != vhost) {
|
||||
return err;
|
||||
|
|
@ -390,7 +390,7 @@ srs_error_t SrsRtmpConn::on_reload_vhost_play(string vhost)
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
|
||||
if (req->vhost != vhost) {
|
||||
return err;
|
||||
|
|
@ -416,7 +416,7 @@ srs_error_t SrsRtmpConn::on_reload_vhost_tcp_nodelay(string vhost)
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
|
||||
if (req->vhost != vhost) {
|
||||
return err;
|
||||
|
|
@ -431,7 +431,7 @@ srs_error_t SrsRtmpConn::on_reload_vhost_realtime(string vhost)
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
|
||||
if (req->vhost != vhost) {
|
||||
return err;
|
||||
|
|
@ -454,7 +454,7 @@ srs_error_t SrsRtmpConn::on_reload_vhost_publish(string vhost)
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
|
||||
if (req->vhost != vhost) {
|
||||
return err;
|
||||
|
|
@ -484,7 +484,7 @@ srs_error_t SrsRtmpConn::service_cycle()
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
|
||||
int out_ack_size = _srs_config->get_out_ack_size(req->vhost);
|
||||
if (out_ack_size && (err = rtmp->set_window_ack_size(out_ack_size)) != srs_success) {
|
||||
|
|
@ -579,7 +579,7 @@ srs_error_t SrsRtmpConn::stream_service_cycle()
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
if ((err = rtmp->identify_client(info->res->stream_id, info->type, req->stream, req->duration)) != srs_success) {
|
||||
return srs_error_wrap(err, "rtmp: identify client");
|
||||
}
|
||||
|
|
@ -657,7 +657,7 @@ srs_error_t SrsRtmpConn::stream_service_cycle()
|
|||
|
||||
// find a source to serve.
|
||||
SrsSharedPtr<SrsLiveSource> live_source;
|
||||
if ((err = _srs_sources->fetch_or_create(req, server, live_source)) != srs_success) {
|
||||
if ((err = _srs_sources->fetch_or_create(req, live_source)) != srs_success) {
|
||||
return srs_error_wrap(err, "rtmp: fetch source");
|
||||
}
|
||||
srs_assert(live_source.get() != NULL);
|
||||
|
|
@ -754,7 +754,7 @@ srs_error_t SrsRtmpConn::check_vhost(bool try_default_vhost)
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
srs_assert(req != NULL);
|
||||
|
||||
SrsConfDirective *vhost = _srs_config->get_vhost(req->vhost, try_default_vhost);
|
||||
|
|
@ -789,7 +789,7 @@ srs_error_t SrsRtmpConn::playing(SrsSharedPtr<SrsLiveSource> source)
|
|||
srs_error_t err = srs_success;
|
||||
|
||||
// Check page referer of player.
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
if (_srs_config->get_refer_enabled(req->vhost)) {
|
||||
if ((err = refer->check(req->pageUrl, _srs_config->get_refer_play(req->vhost))) != srs_success) {
|
||||
return srs_error_wrap(err, "rtmp: referer check");
|
||||
|
|
@ -876,7 +876,7 @@ srs_error_t SrsRtmpConn::do_playing(SrsSharedPtr<SrsLiveSource> source, SrsLiveC
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
srs_assert(req);
|
||||
srs_assert(consumer);
|
||||
|
||||
|
|
@ -1009,7 +1009,7 @@ srs_error_t SrsRtmpConn::publishing(SrsSharedPtr<SrsLiveSource> source)
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
|
||||
if (_srs_config->get_refer_enabled(req->vhost)) {
|
||||
if ((err = refer->check(req->pageUrl, _srs_config->get_refer_publish(req->vhost))) != srs_success) {
|
||||
|
|
@ -1052,7 +1052,7 @@ srs_error_t SrsRtmpConn::do_publishing(SrsSharedPtr<SrsLiveSource> source, SrsPu
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
SrsUniquePtr<SrsPithyPrint> pprint(SrsPithyPrint::create_rtmp_publish());
|
||||
|
||||
// start isolate recv thread.
|
||||
|
|
@ -1151,7 +1151,7 @@ srs_error_t SrsRtmpConn::acquire_publish(SrsSharedPtr<SrsLiveSource> source)
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
|
||||
// Check whether RTMP stream is busy.
|
||||
if (!source->can_publish(info->edge)) {
|
||||
|
|
@ -1404,7 +1404,7 @@ srs_error_t SrsRtmpConn::process_play_control_msg(SrsLiveConsumer *consumer, Srs
|
|||
|
||||
void SrsRtmpConn::set_sock_options()
|
||||
{
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
|
||||
bool nvalue = _srs_config->get_tcp_nodelay(req->vhost);
|
||||
if (nvalue != tcp_nodelay) {
|
||||
|
|
@ -1422,7 +1422,7 @@ srs_error_t SrsRtmpConn::check_edge_token_traverse_auth()
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
srs_assert(req);
|
||||
|
||||
vector<string> args = _srs_config->get_vhost_edge_origin(req->vhost)->args;
|
||||
|
|
@ -1456,7 +1456,7 @@ srs_error_t SrsRtmpConn::do_token_traverse_auth(SrsRtmpClient *client)
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
srs_assert(client);
|
||||
|
||||
client->set_recv_timeout(SRS_CONSTS_RTMP_TIMEOUT);
|
||||
|
|
@ -1491,7 +1491,7 @@ srs_error_t SrsRtmpConn::http_hooks_on_connect()
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
|
||||
if (!_srs_config->get_vhost_http_hooks_enabled(req->vhost)) {
|
||||
return err;
|
||||
|
|
@ -1524,7 +1524,7 @@ srs_error_t SrsRtmpConn::http_hooks_on_connect()
|
|||
|
||||
void SrsRtmpConn::http_hooks_on_close()
|
||||
{
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
|
||||
if (!_srs_config->get_vhost_http_hooks_enabled(req->vhost)) {
|
||||
return;
|
||||
|
|
@ -1555,7 +1555,7 @@ srs_error_t SrsRtmpConn::http_hooks_on_publish()
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
|
||||
if (!_srs_config->get_vhost_http_hooks_enabled(req->vhost)) {
|
||||
return err;
|
||||
|
|
@ -1588,7 +1588,7 @@ srs_error_t SrsRtmpConn::http_hooks_on_publish()
|
|||
|
||||
void SrsRtmpConn::http_hooks_on_unpublish()
|
||||
{
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
|
||||
if (!_srs_config->get_vhost_http_hooks_enabled(req->vhost)) {
|
||||
return;
|
||||
|
|
@ -1619,7 +1619,7 @@ srs_error_t SrsRtmpConn::http_hooks_on_play()
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
|
||||
if (!_srs_config->get_vhost_http_hooks_enabled(req->vhost)) {
|
||||
return err;
|
||||
|
|
@ -1652,7 +1652,7 @@ srs_error_t SrsRtmpConn::http_hooks_on_play()
|
|||
|
||||
void SrsRtmpConn::http_hooks_on_stop()
|
||||
{
|
||||
SrsRequest *req = info->req;
|
||||
ISrsRequest *req = info->req;
|
||||
|
||||
if (!_srs_config->get_vhost_http_hooks_enabled(req->vhost)) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
class SrsServer;
|
||||
class SrsRtmpServer;
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsResponse;
|
||||
class SrsLiveSource;
|
||||
class SrsRefer;
|
||||
|
|
@ -62,7 +62,7 @@ public:
|
|||
// Whether the client connected at the edge server.
|
||||
bool edge;
|
||||
// Original request object from client.
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
// Response object to client.
|
||||
SrsResponse *res;
|
||||
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ SrsRtspPlayStream::~SrsRtspPlayStream()
|
|||
stat->on_disconnect(cid_.c_str(), srs_success);
|
||||
}
|
||||
|
||||
srs_error_t SrsRtspPlayStream::initialize(SrsRequest *req, std::map<uint32_t, SrsRtcTrackDescription *> sub_relations)
|
||||
srs_error_t SrsRtspPlayStream::initialize(ISrsRequest *req, std::map<uint32_t, SrsRtcTrackDescription *> sub_relations)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -850,7 +850,7 @@ srs_error_t SrsRtspConnection::do_teardown()
|
|||
return srs_success;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtspConnection::http_hooks_on_play(SrsRequest *req)
|
||||
srs_error_t SrsRtspConnection::http_hooks_on_play(ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#include <sys/socket.h>
|
||||
#include <vector>
|
||||
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsRtpPacket;
|
||||
class SrsRtspSource;
|
||||
class SrsRtspAudioSendTrack;
|
||||
|
|
@ -42,7 +42,7 @@ private:
|
|||
SrsRtspConnection *session_;
|
||||
|
||||
private:
|
||||
SrsRequest *req_;
|
||||
ISrsRequest *req_;
|
||||
SrsSharedPtr<SrsRtspSource> source_;
|
||||
// key: publish_ssrc, value: send track to process rtp/rtcp
|
||||
std::map<uint32_t, SrsRtspAudioSendTrack *> audio_tracks_;
|
||||
|
|
@ -66,7 +66,7 @@ public:
|
|||
virtual ~SrsRtspPlayStream();
|
||||
|
||||
public:
|
||||
srs_error_t initialize(SrsRequest *request, std::map<uint32_t, SrsRtcTrackDescription *> sub_relations);
|
||||
srs_error_t initialize(ISrsRequest *request, std::map<uint32_t, SrsRtcTrackDescription *> sub_relations);
|
||||
// Interface ISrsRtcSourceChangeCallback
|
||||
public:
|
||||
void on_stream_change(SrsRtcSourceDescription *desc);
|
||||
|
|
@ -101,7 +101,7 @@ private:
|
|||
// TODO: FIXME: Rename it.
|
||||
srs_utime_t last_stun_time;
|
||||
SrsContextId cid_;
|
||||
SrsRequest *request_;
|
||||
ISrsRequest *request_;
|
||||
// The manager object to manage the connection.
|
||||
ISrsResourceManager *manager_;
|
||||
// Each connection start a green thread,
|
||||
|
|
@ -179,7 +179,7 @@ private:
|
|||
srs_error_t do_cycle();
|
||||
|
||||
private:
|
||||
srs_error_t http_hooks_on_play(SrsRequest *req);
|
||||
srs_error_t http_hooks_on_play(ISrsRequest *req);
|
||||
srs_error_t get_ssrc_by_stream_id(uint32_t stream_id, uint32_t *ssrc);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -168,43 +168,49 @@ srs_error_t SrsRtspSourceManager::notify(int event, srs_utime_t interval, srs_ut
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtspSourceManager::fetch_or_create(SrsRequest *r, SrsSharedPtr<SrsRtspSource> &pps)
|
||||
srs_error_t SrsRtspSourceManager::fetch_or_create(ISrsRequest *r, SrsSharedPtr<SrsRtspSource> &pps)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// Use lock to protect coroutine switch.
|
||||
// @bug https://github.com/ossrs/srs/issues/1230
|
||||
SrsLocker(lock);
|
||||
bool created = false;
|
||||
// Should never invoke any function during the locking.
|
||||
if (true) {
|
||||
// Use lock to protect coroutine switch.
|
||||
// @bug https://github.com/ossrs/srs/issues/1230
|
||||
SrsLocker(lock);
|
||||
|
||||
string stream_url = r->get_stream_url();
|
||||
std::map<std::string, SrsSharedPtr<SrsRtspSource> >::iterator it = pool.find(stream_url);
|
||||
string stream_url = r->get_stream_url();
|
||||
std::map<std::string, SrsSharedPtr<SrsRtspSource> >::iterator it = pool.find(stream_url);
|
||||
|
||||
if (it != pool.end()) {
|
||||
SrsSharedPtr<SrsRtspSource> source = it->second;
|
||||
if (it != pool.end()) {
|
||||
SrsSharedPtr<SrsRtspSource> source = it->second;
|
||||
pps = source;
|
||||
} else {
|
||||
SrsSharedPtr<SrsRtspSource> source = SrsSharedPtr<SrsRtspSource>(new SrsRtspSource());
|
||||
srs_trace("new rtsp source, stream_url=%s", stream_url.c_str());
|
||||
pps = source;
|
||||
|
||||
// we always update the request of resource,
|
||||
// for origin auth is on, the token in request maybe invalid,
|
||||
// and we only need to update the token of request, it's simple.
|
||||
source->update_auth(r);
|
||||
pps = source;
|
||||
|
||||
return err;
|
||||
pool[stream_url] = source;
|
||||
created = true;
|
||||
}
|
||||
}
|
||||
|
||||
SrsSharedPtr<SrsRtspSource> source = SrsSharedPtr<SrsRtspSource>(new SrsRtspSource());
|
||||
srs_trace("new rtsp source, stream_url=%s", stream_url.c_str());
|
||||
|
||||
if ((err = source->initialize(r)) != srs_success) {
|
||||
// Initialize source.
|
||||
if (created && (err = pps->initialize(r)) != srs_success) {
|
||||
return srs_error_wrap(err, "init source %s", r->get_stream_url().c_str());
|
||||
}
|
||||
|
||||
pool[stream_url] = source;
|
||||
pps = source;
|
||||
// we always update the request of resource,
|
||||
// for origin auth is on, the token in request maybe invalid,
|
||||
// and we only need to update the token of request, it's simple.
|
||||
if (!created) {
|
||||
pps->update_auth(r);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
SrsSharedPtr<SrsRtspSource> SrsRtspSourceManager::fetch(SrsRequest *r)
|
||||
SrsSharedPtr<SrsRtspSource> SrsRtspSourceManager::fetch(ISrsRequest *r)
|
||||
{
|
||||
// Use lock to protect coroutine switch.
|
||||
// @bug https://github.com/ossrs/srs/issues/1230
|
||||
|
|
@ -255,7 +261,19 @@ SrsRtspSource::~SrsRtspSource()
|
|||
srs_trace("free rtc source id=[%s]", cid.c_str());
|
||||
}
|
||||
|
||||
srs_error_t SrsRtspSource::initialize(SrsRequest *r)
|
||||
// CRITICAL: This method is called AFTER the source has been added to the source pool
|
||||
// in the fetch_or_create pattern (see PR 4449).
|
||||
//
|
||||
// IMPORTANT: All field initialization in this method MUST NOT cause coroutine context switches
|
||||
// before completing the basic field setup.
|
||||
//
|
||||
// If context switches occur before all fields are properly initialized, other coroutines
|
||||
// accessing this source from the pool may encounter uninitialized state, leading to crashes
|
||||
// or undefined behavior.
|
||||
//
|
||||
// This prevents the race condition where multiple coroutines could create duplicate sources
|
||||
// for the same stream when context switches occurred during initialization.
|
||||
srs_error_t SrsRtspSource::initialize(ISrsRequest *r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -285,7 +303,7 @@ bool SrsRtspSource::stream_is_dead()
|
|||
return true;
|
||||
}
|
||||
|
||||
void SrsRtspSource::update_auth(SrsRequest *r)
|
||||
void SrsRtspSource::update_auth(ISrsRequest *r)
|
||||
{
|
||||
req->update_auth(r);
|
||||
}
|
||||
|
|
@ -638,7 +656,7 @@ srs_error_t SrsRtspRtpBuilder::initialize_video_track(SrsVideoCodecId codec)
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtspRtpBuilder::initialize(SrsRequest *r)
|
||||
srs_error_t SrsRtspRtpBuilder::initialize(ISrsRequest *r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsRtpPacket;
|
||||
class SrsRtspSource;
|
||||
class SrsRtspConsumer;
|
||||
|
|
@ -26,6 +26,7 @@ class SrsRtcSourceDescription;
|
|||
class SrsResourceManager;
|
||||
class SrsRtspConnection;
|
||||
class SrsRtpVideoBuilder;
|
||||
class SrsFrameToRtspBridge;
|
||||
|
||||
// The RTSP stream consumer, consume packets from RTSP stream source.
|
||||
class SrsRtspConsumer
|
||||
|
|
@ -89,11 +90,11 @@ public:
|
|||
// create source when fetch from cache failed.
|
||||
// @param r the client request.
|
||||
// @param pps the matched source, if success never be NULL.
|
||||
virtual srs_error_t fetch_or_create(SrsRequest *r, SrsSharedPtr<SrsRtspSource> &pps);
|
||||
virtual srs_error_t fetch_or_create(ISrsRequest *r, SrsSharedPtr<SrsRtspSource> &pps);
|
||||
|
||||
public:
|
||||
// Get the exists source, NULL when not exists.
|
||||
virtual SrsSharedPtr<SrsRtspSource> fetch(SrsRequest *r);
|
||||
virtual SrsSharedPtr<SrsRtspSource> fetch(ISrsRequest *r);
|
||||
};
|
||||
|
||||
// The global RTSP source manager.
|
||||
|
|
@ -112,7 +113,7 @@ private:
|
|||
SrsContextId _source_id;
|
||||
// previous source id.
|
||||
SrsContextId _pre_source_id;
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
// Steam description for this steam.
|
||||
SrsRtcTrackDescription *audio_desc_;
|
||||
SrsRtcTrackDescription *video_desc_;
|
||||
|
|
@ -134,7 +135,7 @@ public:
|
|||
virtual ~SrsRtspSource();
|
||||
|
||||
public:
|
||||
virtual srs_error_t initialize(SrsRequest *r);
|
||||
virtual srs_error_t initialize(ISrsRequest *r);
|
||||
|
||||
public:
|
||||
// Whether stream is dead, which is no publisher or player.
|
||||
|
|
@ -142,7 +143,7 @@ public:
|
|||
|
||||
public:
|
||||
// Update the authentication information in request.
|
||||
virtual void update_auth(SrsRequest *r);
|
||||
virtual void update_auth(ISrsRequest *r);
|
||||
|
||||
private:
|
||||
// The stream source changed.
|
||||
|
|
@ -188,7 +189,7 @@ public:
|
|||
class SrsRtspRtpBuilder
|
||||
{
|
||||
private:
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
SrsFrameToRtspBridge *bridge_;
|
||||
// The format, codec information.
|
||||
SrsRtmpFormat *format;
|
||||
|
|
@ -219,7 +220,7 @@ private:
|
|||
srs_error_t initialize_video_track(SrsVideoCodecId codec);
|
||||
|
||||
public:
|
||||
virtual srs_error_t initialize(SrsRequest *r);
|
||||
virtual srs_error_t initialize(ISrsRequest *r);
|
||||
virtual srs_error_t on_publish();
|
||||
virtual void on_unpublish();
|
||||
virtual srs_error_t on_frame(SrsSharedPtrMessage *frame);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ SrsSecurity::~SrsSecurity()
|
|||
{
|
||||
}
|
||||
|
||||
srs_error_t SrsSecurity::check(SrsRtmpConnType type, string ip, SrsRequest *req)
|
||||
srs_error_t SrsSecurity::check(SrsRtmpConnType type, string ip, ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -33,7 +33,7 @@ srs_error_t SrsSecurity::check(SrsRtmpConnType type, string ip, SrsRequest *req)
|
|||
return do_check(rules, type, ip, req);
|
||||
}
|
||||
|
||||
srs_error_t SrsSecurity::do_check(SrsConfDirective *rules, SrsRtmpConnType type, string ip, SrsRequest *req)
|
||||
srs_error_t SrsSecurity::do_check(SrsConfDirective *rules, SrsRtmpConnType type, string ip, ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,10 +28,10 @@ public:
|
|||
// @param type the client type, publish or play.
|
||||
// @param ip the ip address of client.
|
||||
// @param req the request object of client.
|
||||
virtual srs_error_t check(SrsRtmpConnType type, std::string ip, SrsRequest *req);
|
||||
virtual srs_error_t check(SrsRtmpConnType type, std::string ip, ISrsRequest *req);
|
||||
|
||||
private:
|
||||
virtual srs_error_t do_check(SrsConfDirective *rules, SrsRtmpConnType type, std::string ip, SrsRequest *req);
|
||||
virtual srs_error_t do_check(SrsConfDirective *rules, SrsRtmpConnType type, std::string ip, ISrsRequest *req);
|
||||
virtual srs_error_t allow_check(SrsConfDirective *rules, SrsRtmpConnType type, std::string ip);
|
||||
virtual srs_error_t deny_check(SrsConfDirective *rules, SrsRtmpConnType type, std::string ip);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1396,7 +1396,7 @@ srs_error_t SrsServer::on_reload_listen()
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsServer::on_publish(SrsRequest *r)
|
||||
srs_error_t SrsServer::on_publish(ISrsRequest *r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -1412,7 +1412,7 @@ srs_error_t SrsServer::on_publish(SrsRequest *r)
|
|||
return err;
|
||||
}
|
||||
|
||||
void SrsServer::on_unpublish(SrsRequest *r)
|
||||
void SrsServer::on_unpublish(ISrsRequest *r)
|
||||
{
|
||||
http_server->http_unmount(r);
|
||||
|
||||
|
|
|
|||
|
|
@ -256,8 +256,8 @@ public:
|
|||
virtual srs_error_t on_reload_listen();
|
||||
// Interface ISrsLiveSourceHandler
|
||||
public:
|
||||
virtual srs_error_t on_publish(SrsRequest *r);
|
||||
virtual void on_unpublish(SrsRequest *r);
|
||||
virtual srs_error_t on_publish(ISrsRequest *r);
|
||||
virtual void on_unpublish(ISrsRequest *r);
|
||||
};
|
||||
|
||||
// The SRS server adapter, the master server.
|
||||
|
|
|
|||
|
|
@ -19,8 +19,10 @@ using namespace std;
|
|||
#include <srs_app_hds.hpp>
|
||||
#include <srs_app_hls.hpp>
|
||||
#include <srs_app_http_hooks.hpp>
|
||||
#include <srs_app_hybrid.hpp>
|
||||
#include <srs_app_ng_exec.hpp>
|
||||
#include <srs_app_rtc_source.hpp>
|
||||
#include <srs_app_server.hpp>
|
||||
#include <srs_app_statistic.hpp>
|
||||
#include <srs_core_autofree.hpp>
|
||||
#include <srs_kernel_buffer.hpp>
|
||||
|
|
@ -857,7 +859,7 @@ SrsOriginHub::~SrsOriginHub()
|
|||
#endif
|
||||
}
|
||||
|
||||
srs_error_t SrsOriginHub::initialize(SrsSharedPtr<SrsLiveSource> s, SrsRequest *r)
|
||||
srs_error_t SrsOriginHub::initialize(SrsSharedPtr<SrsLiveSource> s, ISrsRequest *r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -1524,7 +1526,7 @@ srs_error_t SrsOriginHub::create_backend_forwarders(bool &applied)
|
|||
std::string url = *it;
|
||||
|
||||
// create temp Request by url
|
||||
SrsUniquePtr<SrsRequest> req(new SrsRequest());
|
||||
SrsUniquePtr<ISrsRequest> req(new SrsRequest());
|
||||
srs_parse_rtmp_url(url, req->tcUrl, req->stream);
|
||||
srs_discovery_tc_url(req->tcUrl, req->schema, req->host, req->vhost, req->app, req->stream, req->port, req->param);
|
||||
|
||||
|
|
@ -1760,42 +1762,53 @@ srs_error_t SrsLiveSourceManager::initialize()
|
|||
return setup_ticks();
|
||||
}
|
||||
|
||||
srs_error_t SrsLiveSourceManager::fetch_or_create(SrsRequest *r, ISrsLiveSourceHandler *h, SrsSharedPtr<SrsLiveSource> &pps)
|
||||
srs_error_t SrsLiveSourceManager::fetch_or_create(ISrsRequest *r, SrsSharedPtr<SrsLiveSource> &pps)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// Use lock to protect coroutine switch.
|
||||
// @bug https://github.com/ossrs/srs/issues/1230
|
||||
// TODO: FIXME: Use smaller scope lock.
|
||||
SrsLocker(lock);
|
||||
bool created = false;
|
||||
// Should never invoke any function during the locking.
|
||||
if (true) {
|
||||
// Use lock to protect coroutine switch.
|
||||
// @bug https://github.com/ossrs/srs/issues/1230
|
||||
// TODO: FIXME: Use smaller scope lock.
|
||||
SrsLocker(lock);
|
||||
|
||||
string stream_url = r->get_stream_url();
|
||||
std::map<std::string, SrsSharedPtr<SrsLiveSource> >::iterator it = pool.find(stream_url);
|
||||
string stream_url = r->get_stream_url();
|
||||
std::map<std::string, SrsSharedPtr<SrsLiveSource> >::iterator it = pool.find(stream_url);
|
||||
|
||||
if (it != pool.end()) {
|
||||
SrsSharedPtr<SrsLiveSource> &source = it->second;
|
||||
if (it != pool.end()) {
|
||||
SrsSharedPtr<SrsLiveSource> &source = it->second;
|
||||
pps = source;
|
||||
} else {
|
||||
SrsSharedPtr<SrsLiveSource> source = new SrsLiveSource();
|
||||
srs_trace("new live source, stream_url=%s", stream_url.c_str());
|
||||
pps = source;
|
||||
|
||||
// we always update the request of resource,
|
||||
// for origin auth is on, the token in request maybe invalid,
|
||||
// and we only need to update the token of request, it's simple.
|
||||
source->update_auth(r);
|
||||
pps = source;
|
||||
return err;
|
||||
// Callback to notify request of source creation
|
||||
r->on_source_created();
|
||||
|
||||
pool[stream_url] = source;
|
||||
created = true;
|
||||
}
|
||||
}
|
||||
|
||||
SrsSharedPtr<SrsLiveSource> source = new SrsLiveSource();
|
||||
srs_trace("new live source, stream_url=%s", stream_url.c_str());
|
||||
|
||||
if ((err = source->initialize(source, r, h)) != srs_success) {
|
||||
// Initialize source with the wrapper of itself.
|
||||
if (created && (err = pps->initialize(pps, r)) != srs_success) {
|
||||
return srs_error_wrap(err, "init source %s", r->get_stream_url().c_str());
|
||||
}
|
||||
|
||||
pool[stream_url] = source;
|
||||
pps = source;
|
||||
// we always update the request of resource,
|
||||
// for origin auth is on, the token in request maybe invalid,
|
||||
// and we only need to update the token of request, it's simple.
|
||||
if (!created) {
|
||||
pps->update_auth(r);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
SrsSharedPtr<SrsLiveSource> SrsLiveSourceManager::fetch(SrsRequest *r)
|
||||
SrsSharedPtr<SrsLiveSource> SrsLiveSourceManager::fetch(ISrsRequest *r)
|
||||
{
|
||||
// Use lock to protect coroutine switch.
|
||||
// @bug https://github.com/ossrs/srs/issues/1230
|
||||
|
|
@ -1886,7 +1899,6 @@ SrsLiveSource::SrsLiveSource()
|
|||
stream_die_at_ = 0;
|
||||
publisher_idle_at_ = 0;
|
||||
|
||||
handler = NULL;
|
||||
bridge_ = NULL;
|
||||
|
||||
play_edge = new SrsPlayEdge();
|
||||
|
|
@ -1985,17 +1997,30 @@ bool SrsLiveSource::publisher_is_idle_for(srs_utime_t timeout)
|
|||
return false;
|
||||
}
|
||||
|
||||
srs_error_t SrsLiveSource::initialize(SrsSharedPtr<SrsLiveSource> wrapper, SrsRequest *r, ISrsLiveSourceHandler *h)
|
||||
// CRITICAL: This method is called AFTER the source has been added to the source pool
|
||||
// in the fetch_or_create pattern (see PR 4449).
|
||||
//
|
||||
// IMPORTANT: All field initialization in this method MUST NOT cause coroutine context switches
|
||||
// before completing the basic field setup.
|
||||
//
|
||||
// If context switches occur before all fields are properly initialized, other coroutines
|
||||
// accessing this source from the pool may encounter uninitialized state, leading to crashes
|
||||
// or undefined behavior.
|
||||
//
|
||||
// This prevents the race condition where multiple coroutines could create duplicate sources
|
||||
// for the same stream when context switches occurred during initialization.
|
||||
srs_error_t SrsLiveSource::initialize(SrsSharedPtr<SrsLiveSource> wrapper, ISrsRequest *r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
srs_assert(h);
|
||||
srs_assert(!req);
|
||||
|
||||
handler = h;
|
||||
req = r->copy();
|
||||
atc = _srs_config->get_atc(req->vhost);
|
||||
|
||||
jitter_algorithm = (SrsRtmpJitterAlgorithm)_srs_config->get_time_jitter(req->vhost);
|
||||
mix_correct = _srs_config->get_mix_correct(req->vhost);
|
||||
|
||||
if ((err = format_->initialize()) != srs_success) {
|
||||
return srs_error_wrap(err, "format initialize");
|
||||
}
|
||||
|
|
@ -2003,10 +2028,6 @@ srs_error_t SrsLiveSource::initialize(SrsSharedPtr<SrsLiveSource> wrapper, SrsRe
|
|||
// Setup the SPS/PPS parsing strategy.
|
||||
format_->try_annexb_first = _srs_config->try_annexb_first(r->vhost);
|
||||
|
||||
if ((err = hub->initialize(wrapper, req)) != srs_success) {
|
||||
return srs_error_wrap(err, "hub");
|
||||
}
|
||||
|
||||
if ((err = play_edge->initialize(wrapper, req)) != srs_success) {
|
||||
return srs_error_wrap(err, "edge(play)");
|
||||
}
|
||||
|
|
@ -2017,8 +2038,9 @@ srs_error_t SrsLiveSource::initialize(SrsSharedPtr<SrsLiveSource> wrapper, SrsRe
|
|||
srs_utime_t queue_size = _srs_config->get_queue_length(req->vhost);
|
||||
publish_edge->set_queue_size(queue_size);
|
||||
|
||||
jitter_algorithm = (SrsRtmpJitterAlgorithm)_srs_config->get_time_jitter(req->vhost);
|
||||
mix_correct = _srs_config->get_mix_correct(req->vhost);
|
||||
if ((err = hub->initialize(wrapper, req)) != srs_success) {
|
||||
return srs_error_wrap(err, "hub");
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
@ -2151,7 +2173,7 @@ bool SrsLiveSource::inactive()
|
|||
return can_publish_;
|
||||
}
|
||||
|
||||
void SrsLiveSource::update_auth(SrsRequest *r)
|
||||
void SrsLiveSource::update_auth(ISrsRequest *r)
|
||||
{
|
||||
req->update_auth(r);
|
||||
}
|
||||
|
|
@ -2588,6 +2610,7 @@ srs_error_t SrsLiveSource::on_publish()
|
|||
}
|
||||
|
||||
// notify the handler.
|
||||
ISrsLiveSourceHandler *handler = _srs_hybrid->srs()->instance();
|
||||
srs_assert(handler);
|
||||
if ((err = handler->on_publish(req)) != srs_success) {
|
||||
return srs_error_wrap(err, "handle publish");
|
||||
|
|
@ -2636,7 +2659,9 @@ void SrsLiveSource::on_unpublish()
|
|||
_source_id = SrsContextId();
|
||||
|
||||
// notify the handler.
|
||||
ISrsLiveSourceHandler *handler = _srs_hybrid->srs()->instance();
|
||||
srs_assert(handler);
|
||||
|
||||
SrsStatistic *stat = SrsStatistic::instance();
|
||||
stat->on_stream_close(req);
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class SrsCommonMessage;
|
|||
class SrsOnMetaDataPacket;
|
||||
class SrsSharedPtrMessage;
|
||||
class SrsForwarder;
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsStSocket;
|
||||
class SrsRtmpServer;
|
||||
class SrsEdgeProxyContext;
|
||||
|
|
@ -306,9 +306,9 @@ public:
|
|||
|
||||
public:
|
||||
// when stream start publish, mount stream.
|
||||
virtual srs_error_t on_publish(SrsRequest *r) = 0;
|
||||
virtual srs_error_t on_publish(ISrsRequest *r) = 0;
|
||||
// when stream stop publish, unmount stream.
|
||||
virtual void on_unpublish(SrsRequest *r) = 0;
|
||||
virtual void on_unpublish(ISrsRequest *r) = 0;
|
||||
};
|
||||
|
||||
// The mix queue to correct the timestamp for mix_correct algorithm.
|
||||
|
|
@ -339,7 +339,7 @@ private:
|
|||
SrsLiveSource *source_;
|
||||
|
||||
private:
|
||||
SrsRequest *req_;
|
||||
ISrsRequest *req_;
|
||||
bool is_active;
|
||||
|
||||
private:
|
||||
|
|
@ -367,7 +367,7 @@ public:
|
|||
public:
|
||||
// Initialize the hub with source and request.
|
||||
// @param r The request object, managed by source.
|
||||
virtual srs_error_t initialize(SrsSharedPtr<SrsLiveSource> s, SrsRequest *r);
|
||||
virtual srs_error_t initialize(SrsSharedPtr<SrsLiveSource> s, ISrsRequest *r);
|
||||
// Dispose the hub, release utilities resource,
|
||||
// For example, delete all HLS pieces.
|
||||
virtual void dispose();
|
||||
|
|
@ -492,11 +492,11 @@ public:
|
|||
// @param r the client request.
|
||||
// @param h the event handler for source.
|
||||
// @param pps the matched source, if success never be NULL.
|
||||
virtual srs_error_t fetch_or_create(SrsRequest *r, ISrsLiveSourceHandler *h, SrsSharedPtr<SrsLiveSource> &pps);
|
||||
virtual srs_error_t fetch_or_create(ISrsRequest *r, SrsSharedPtr<SrsLiveSource> &pps);
|
||||
|
||||
public:
|
||||
// Get the exists source, NULL when not exists.
|
||||
virtual SrsSharedPtr<SrsLiveSource> fetch(SrsRequest *r);
|
||||
virtual SrsSharedPtr<SrsLiveSource> fetch(ISrsRequest *r);
|
||||
|
||||
public:
|
||||
// dispose and cycle all sources.
|
||||
|
|
@ -529,7 +529,7 @@ private:
|
|||
// previous source id.
|
||||
SrsContextId _pre_source_id;
|
||||
// deep copy of client request.
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
// To delivery stream to clients.
|
||||
std::vector<SrsLiveConsumer *> consumers;
|
||||
// The time jitter algorithm for vhost.
|
||||
|
|
@ -547,8 +547,6 @@ private:
|
|||
bool is_monotonically_increase;
|
||||
// The time of the packet we just got.
|
||||
int64_t last_packet_time;
|
||||
// The event handler.
|
||||
ISrsLiveSourceHandler *handler;
|
||||
// The source bridge for other source.
|
||||
ISrsStreamBridge *bridge_;
|
||||
// The edge control service
|
||||
|
|
@ -585,7 +583,7 @@ public:
|
|||
|
||||
public:
|
||||
// Initialize the hls with handlers.
|
||||
virtual srs_error_t initialize(SrsSharedPtr<SrsLiveSource> wrapper, SrsRequest *r, ISrsLiveSourceHandler *h);
|
||||
virtual srs_error_t initialize(SrsSharedPtr<SrsLiveSource> wrapper, ISrsRequest *r);
|
||||
// Bridge to other source, forward packets to it.
|
||||
void set_bridge(ISrsStreamBridge *v);
|
||||
// Interface ISrsReloadHandler
|
||||
|
|
@ -602,7 +600,7 @@ public:
|
|||
// @remark For edge, it's inactive util stream has been pulled from origin.
|
||||
virtual bool inactive();
|
||||
// Update the authentication information in request.
|
||||
virtual void update_auth(SrsRequest *r);
|
||||
virtual void update_auth(ISrsRequest *r);
|
||||
|
||||
public:
|
||||
virtual bool can_publish(bool is_edge);
|
||||
|
|
|
|||
|
|
@ -372,7 +372,7 @@ srs_error_t SrsMpegtsSrtConn::acquire_publish()
|
|||
return srs_error_new(ERROR_SYSTEM_STREAM_BUSY, "live_source stream %s busy", req_->get_stream_url().c_str());
|
||||
}
|
||||
|
||||
if ((err = _srs_sources->fetch_or_create(req_, _srs_hybrid->srs()->instance(), live_source)) != srs_success) {
|
||||
if ((err = _srs_sources->fetch_or_create(req_, live_source)) != srs_success) {
|
||||
return srs_error_wrap(err, "create source");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ private:
|
|||
int port_;
|
||||
SrsCoroutine *trd_;
|
||||
|
||||
SrsRequest *req_;
|
||||
ISrsRequest *req_;
|
||||
SrsSharedPtr<SrsSrtSource> srt_source_;
|
||||
SrsSecurity *security_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -151,39 +151,63 @@ srs_error_t SrsSrtSourceManager::notify(int event, srs_utime_t interval, srs_uti
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsSrtSourceManager::fetch_or_create(SrsRequest *r, SrsSharedPtr<SrsSrtSource> &pps)
|
||||
srs_error_t SrsSrtSourceManager::fetch_or_create(ISrsRequest *r, SrsSharedPtr<SrsSrtSource> &pps)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
bool created = false;
|
||||
// Should never invoke any function during the locking.
|
||||
if (true) {
|
||||
// Use lock to protect coroutine switch.
|
||||
// @bug https://github.com/ossrs/srs/issues/1230
|
||||
SrsLocker(lock);
|
||||
|
||||
string stream_url = r->get_stream_url();
|
||||
std::map<std::string, SrsSharedPtr<SrsSrtSource> >::iterator it = pool.find(stream_url);
|
||||
if (it != pool.end()) {
|
||||
SrsSharedPtr<SrsSrtSource> source = it->second;
|
||||
pps = source;
|
||||
} else {
|
||||
SrsSharedPtr<SrsSrtSource> source(new SrsSrtSource());
|
||||
srs_trace("new srt source, stream_url=%s", stream_url.c_str());
|
||||
pps = source;
|
||||
|
||||
pool[stream_url] = source;
|
||||
created = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize source.
|
||||
if (created && (err = pps->initialize(r)) != srs_success) {
|
||||
return srs_error_wrap(err, "init source %s", r->get_stream_url().c_str());
|
||||
}
|
||||
|
||||
// we always update the request of resource,
|
||||
// for origin auth is on, the token in request maybe invalid,
|
||||
// and we only need to update the token of request, it's simple.
|
||||
if (!created) {
|
||||
pps->update_auth(r);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
SrsSharedPtr<SrsSrtSource> SrsSrtSourceManager::fetch(ISrsRequest *r)
|
||||
{
|
||||
// Use lock to protect coroutine switch.
|
||||
// @bug https://github.com/ossrs/srs/issues/1230
|
||||
SrsLocker(lock);
|
||||
|
||||
string stream_url = r->get_stream_url();
|
||||
std::map<std::string, SrsSharedPtr<SrsSrtSource> >::iterator it = pool.find(stream_url);
|
||||
if (it != pool.end()) {
|
||||
SrsSharedPtr<SrsSrtSource> source = it->second;
|
||||
|
||||
// we always update the request of resource,
|
||||
// for origin auth is on, the token in request maybe invalid,
|
||||
// and we only need to update the token of request, it's simple.
|
||||
source->update_auth(r);
|
||||
pps = source;
|
||||
|
||||
return err;
|
||||
SrsSharedPtr<SrsSrtSource> source;
|
||||
if (it == pool.end()) {
|
||||
return source;
|
||||
}
|
||||
|
||||
SrsSharedPtr<SrsSrtSource> source(new SrsSrtSource());
|
||||
srs_trace("new srt source, stream_url=%s", stream_url.c_str());
|
||||
|
||||
if ((err = source->initialize(r)) != srs_success) {
|
||||
return srs_error_wrap(err, "init source %s", r->get_stream_url().c_str());
|
||||
}
|
||||
|
||||
pool[stream_url] = source;
|
||||
pps = source;
|
||||
|
||||
return err;
|
||||
source = it->second;
|
||||
return source;
|
||||
}
|
||||
|
||||
SrsSrtSourceManager *_srs_srt_sources = NULL;
|
||||
|
|
@ -326,7 +350,7 @@ void SrsSrtFrameBuilder::on_unpublish()
|
|||
{
|
||||
}
|
||||
|
||||
srs_error_t SrsSrtFrameBuilder::initialize(SrsRequest *req)
|
||||
srs_error_t SrsSrtFrameBuilder::initialize(ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -927,7 +951,19 @@ SrsSrtSource::~SrsSrtSource()
|
|||
srs_trace("free srt source id=[%s]", cid.c_str());
|
||||
}
|
||||
|
||||
srs_error_t SrsSrtSource::initialize(SrsRequest *r)
|
||||
// CRITICAL: This method is called AFTER the source has been added to the source pool
|
||||
// in the fetch_or_create pattern (see PR 4449).
|
||||
//
|
||||
// IMPORTANT: All field initialization in this method MUST NOT cause coroutine context switches
|
||||
// before completing the basic field setup.
|
||||
//
|
||||
// If context switches occur before all fields are properly initialized, other coroutines
|
||||
// accessing this source from the pool may encounter uninitialized state, leading to crashes
|
||||
// or undefined behavior.
|
||||
//
|
||||
// This prevents the race condition where multiple coroutines could create duplicate sources
|
||||
// for the same stream when context switches occurred during initialization.
|
||||
srs_error_t SrsSrtSource::initialize(ISrsRequest *r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -990,7 +1026,7 @@ SrsContextId SrsSrtSource::pre_source_id()
|
|||
return _pre_source_id;
|
||||
}
|
||||
|
||||
void SrsSrtSource::update_auth(SrsRequest *r)
|
||||
void SrsSrtSource::update_auth(ISrsRequest *r)
|
||||
{
|
||||
req->update_auth(r);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
#include <srs_protocol_st.hpp>
|
||||
|
||||
class SrsSharedPtrMessage;
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsLiveSource;
|
||||
class SrsSrtSource;
|
||||
class SrsAlonePithyPrint;
|
||||
|
|
@ -73,7 +73,11 @@ public:
|
|||
// create source when fetch from cache failed.
|
||||
// @param r the client request.
|
||||
// @param pps the matched source, if success never be NULL.
|
||||
virtual srs_error_t fetch_or_create(SrsRequest *r, SrsSharedPtr<SrsSrtSource> &pps);
|
||||
virtual srs_error_t fetch_or_create(ISrsRequest *r, SrsSharedPtr<SrsSrtSource> &pps);
|
||||
|
||||
public:
|
||||
// Get the exists source, NULL when not exists.
|
||||
virtual SrsSharedPtr<SrsSrtSource> fetch(ISrsRequest *r);
|
||||
};
|
||||
|
||||
// Global singleton instance.
|
||||
|
|
@ -117,7 +121,7 @@ public:
|
|||
virtual ~SrsSrtFrameBuilder();
|
||||
|
||||
public:
|
||||
srs_error_t initialize(SrsRequest *r);
|
||||
srs_error_t initialize(ISrsRequest *r);
|
||||
|
||||
public:
|
||||
virtual srs_error_t on_publish();
|
||||
|
|
@ -156,7 +160,7 @@ private:
|
|||
std::string audio_sh_;
|
||||
|
||||
private:
|
||||
SrsRequest *req_;
|
||||
ISrsRequest *req_;
|
||||
|
||||
private:
|
||||
// SRT to rtmp, video stream id.
|
||||
|
|
@ -174,7 +178,7 @@ public:
|
|||
virtual ~SrsSrtSource();
|
||||
|
||||
public:
|
||||
virtual srs_error_t initialize(SrsRequest *r);
|
||||
virtual srs_error_t initialize(ISrsRequest *r);
|
||||
|
||||
public:
|
||||
// Whether stream is dead, which is no publisher or player.
|
||||
|
|
@ -187,7 +191,7 @@ public:
|
|||
virtual SrsContextId source_id();
|
||||
virtual SrsContextId pre_source_id();
|
||||
// Update the authentication information in request.
|
||||
virtual void update_auth(SrsRequest *r);
|
||||
virtual void update_auth(ISrsRequest *r);
|
||||
|
||||
public:
|
||||
void set_bridge(ISrsStreamBridge *bridge);
|
||||
|
|
@ -214,7 +218,7 @@ private:
|
|||
SrsContextId _source_id;
|
||||
// previous source id.
|
||||
SrsContextId _pre_source_id;
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
// To delivery packets to clients.
|
||||
std::vector<SrsSrtConsumer *> consumers;
|
||||
bool can_publish_;
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ bool srs_srt_streamid_info(const std::string &streamid, SrtMode &mode, std::stri
|
|||
return true;
|
||||
}
|
||||
|
||||
bool srs_srt_streamid_to_request(const std::string &streamid, SrtMode &mode, SrsRequest *request)
|
||||
bool srs_srt_streamid_to_request(const std::string &streamid, SrtMode &mode, ISrsRequest *request)
|
||||
{
|
||||
string url_subpath = "";
|
||||
bool ret = srs_srt_streamid_info(streamid, mode, request->vhost, url_subpath);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
#include <srs_kernel_log.hpp>
|
||||
#include <srs_protocol_utility.hpp>
|
||||
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
|
||||
enum SrtMode {
|
||||
SrtModePull = 1,
|
||||
|
|
@ -25,6 +25,6 @@ enum SrtMode {
|
|||
extern bool srs_srt_streamid_info(const std::string &streamid, SrtMode &mode, std::string &vhost, std::string &url_subpath);
|
||||
|
||||
// SRT streamid to request.
|
||||
extern bool srs_srt_streamid_to_request(const std::string &streamid, SrtMode &mode, SrsRequest *request);
|
||||
extern bool srs_srt_streamid_to_request(const std::string &streamid, SrtMode &mode, ISrsRequest *request);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ SrsStatisticClient *SrsStatistic::find_client(string client_id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
srs_error_t SrsStatistic::on_video_info(SrsRequest *req, SrsVideoCodecId vcodec, int profile, int level, int width, int height)
|
||||
srs_error_t SrsStatistic::on_video_info(ISrsRequest *req, SrsVideoCodecId vcodec, int profile, int level, int width, int height)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -372,7 +372,7 @@ srs_error_t SrsStatistic::on_video_info(SrsRequest *req, SrsVideoCodecId vcodec,
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsStatistic::on_audio_info(SrsRequest *req, SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate, SrsAudioChannels asound_type, SrsAacObjectType aac_object)
|
||||
srs_error_t SrsStatistic::on_audio_info(ISrsRequest *req, SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate, SrsAudioChannels asound_type, SrsAacObjectType aac_object)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -388,7 +388,7 @@ srs_error_t SrsStatistic::on_audio_info(SrsRequest *req, SrsAudioCodecId acodec,
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsStatistic::on_video_frames(SrsRequest *req, int nb_frames)
|
||||
srs_error_t SrsStatistic::on_video_frames(ISrsRequest *req, int nb_frames)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -400,7 +400,7 @@ srs_error_t SrsStatistic::on_video_frames(SrsRequest *req, int nb_frames)
|
|||
return err;
|
||||
}
|
||||
|
||||
void SrsStatistic::on_stream_publish(SrsRequest *req, std::string publisher_id)
|
||||
void SrsStatistic::on_stream_publish(ISrsRequest *req, std::string publisher_id)
|
||||
{
|
||||
SrsStatisticVhost *vhost = create_vhost(req);
|
||||
SrsStatisticStream *stream = create_stream(vhost, req);
|
||||
|
|
@ -408,14 +408,14 @@ void SrsStatistic::on_stream_publish(SrsRequest *req, std::string publisher_id)
|
|||
stream->publish(publisher_id);
|
||||
}
|
||||
|
||||
void SrsStatistic::on_stream_close(SrsRequest *req)
|
||||
void SrsStatistic::on_stream_close(ISrsRequest *req)
|
||||
{
|
||||
SrsStatisticVhost *vhost = create_vhost(req);
|
||||
SrsStatisticStream *stream = create_stream(vhost, req);
|
||||
stream->close();
|
||||
}
|
||||
|
||||
srs_error_t SrsStatistic::on_client(std::string id, SrsRequest *req, ISrsExpire *conn, SrsRtmpConnType type)
|
||||
srs_error_t SrsStatistic::on_client(std::string id, ISrsRequest *req, ISrsExpire *conn, SrsRtmpConnType type)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -734,7 +734,7 @@ void SrsStatistic::dumps_cls_streams(SrsClsSugars *sugars)
|
|||
}
|
||||
#endif
|
||||
|
||||
SrsStatisticVhost *SrsStatistic::create_vhost(SrsRequest *req)
|
||||
SrsStatisticVhost *SrsStatistic::create_vhost(ISrsRequest *req)
|
||||
{
|
||||
SrsStatisticVhost *vhost = NULL;
|
||||
|
||||
|
|
@ -752,7 +752,7 @@ SrsStatisticVhost *SrsStatistic::create_vhost(SrsRequest *req)
|
|||
return vhost;
|
||||
}
|
||||
|
||||
SrsStatisticStream *SrsStatistic::create_stream(SrsStatisticVhost *vhost, SrsRequest *req)
|
||||
SrsStatisticStream *SrsStatistic::create_stream(SrsStatisticVhost *vhost, ISrsRequest *req)
|
||||
{
|
||||
// To identify a stream, use url without extension, for example, the bellow are the same stream:
|
||||
// ossrs.io/live/livestream
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
class SrsKbps;
|
||||
class SrsWallClock;
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class ISrsExpire;
|
||||
class SrsJsonObject;
|
||||
class SrsJsonArray;
|
||||
|
|
@ -113,7 +113,7 @@ public:
|
|||
|
||||
public:
|
||||
SrsStatisticStream *stream;
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
SrsRtmpConnType type;
|
||||
std::string id;
|
||||
srs_utime_t create;
|
||||
|
|
@ -183,19 +183,19 @@ public:
|
|||
|
||||
public:
|
||||
// When got video info for stream.
|
||||
virtual srs_error_t on_video_info(SrsRequest *req, SrsVideoCodecId vcodec, int avc_profile, int avc_level, int width, int height);
|
||||
virtual srs_error_t on_video_info(ISrsRequest *req, SrsVideoCodecId vcodec, int avc_profile, int avc_level, int width, int height);
|
||||
// When got audio info for stream.
|
||||
virtual srs_error_t on_audio_info(SrsRequest *req, SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate,
|
||||
virtual srs_error_t on_audio_info(ISrsRequest *req, SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate,
|
||||
SrsAudioChannels asound_type, SrsAacObjectType aac_object);
|
||||
// When got videos, update the frames.
|
||||
// We only stat the total number of video frames.
|
||||
virtual srs_error_t on_video_frames(SrsRequest *req, int nb_frames);
|
||||
virtual srs_error_t on_video_frames(ISrsRequest *req, int nb_frames);
|
||||
// When publish stream.
|
||||
// @param req the request object of publish connection.
|
||||
// @param publisher_id The id of publish connection.
|
||||
virtual void on_stream_publish(SrsRequest *req, std::string publisher_id);
|
||||
virtual void on_stream_publish(ISrsRequest *req, std::string publisher_id);
|
||||
// When close stream.
|
||||
virtual void on_stream_close(SrsRequest *req);
|
||||
virtual void on_stream_close(ISrsRequest *req);
|
||||
|
||||
public:
|
||||
// When got a client to publish/play stream,
|
||||
|
|
@ -203,7 +203,7 @@ public:
|
|||
// @param req, the client request object.
|
||||
// @param conn, the physical absract connection object.
|
||||
// @param type, the type of connection.
|
||||
virtual srs_error_t on_client(std::string id, SrsRequest *req, ISrsExpire *conn, SrsRtmpConnType type);
|
||||
virtual srs_error_t on_client(std::string id, ISrsRequest *req, ISrsExpire *conn, SrsRtmpConnType type);
|
||||
// Client disconnect
|
||||
// @remark the on_disconnect always call, while the on_client is call when
|
||||
// only got the request object, so the client specified by id maybe not
|
||||
|
|
@ -248,8 +248,8 @@ public:
|
|||
void dumps_cls_streams(SrsClsSugars *sugars);
|
||||
#endif
|
||||
private:
|
||||
virtual SrsStatisticVhost *create_vhost(SrsRequest *req);
|
||||
virtual SrsStatisticStream *create_stream(SrsStatisticVhost *vhost, SrsRequest *req);
|
||||
virtual SrsStatisticVhost *create_vhost(ISrsRequest *req);
|
||||
virtual SrsStatisticStream *create_stream(SrsStatisticVhost *vhost, ISrsRequest *req);
|
||||
|
||||
public:
|
||||
// Dumps exporter metrics.
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ SrsFrameToRtmpBridge::~SrsFrameToRtmpBridge()
|
|||
{
|
||||
}
|
||||
|
||||
srs_error_t SrsFrameToRtmpBridge::initialize(SrsRequest *r)
|
||||
srs_error_t SrsFrameToRtmpBridge::initialize(ISrsRequest *r)
|
||||
{
|
||||
return srs_success;
|
||||
}
|
||||
|
|
@ -82,7 +82,7 @@ SrsFrameToRtcBridge::~SrsFrameToRtcBridge()
|
|||
#endif
|
||||
}
|
||||
|
||||
srs_error_t SrsFrameToRtcBridge::initialize(SrsRequest *r)
|
||||
srs_error_t SrsFrameToRtcBridge::initialize(ISrsRequest *r)
|
||||
{
|
||||
#ifdef SRS_FFMPEG_FIT
|
||||
return rtp_builder_->initialize(r);
|
||||
|
|
@ -148,7 +148,7 @@ SrsFrameToRtspBridge::~SrsFrameToRtspBridge()
|
|||
srs_freep(rtp_builder_);
|
||||
}
|
||||
|
||||
srs_error_t SrsFrameToRtspBridge::initialize(SrsRequest *r)
|
||||
srs_error_t SrsFrameToRtspBridge::initialize(ISrsRequest *r)
|
||||
{
|
||||
return rtp_builder_->initialize(r);
|
||||
}
|
||||
|
|
@ -201,7 +201,7 @@ SrsCompositeBridge::~SrsCompositeBridge()
|
|||
}
|
||||
}
|
||||
|
||||
srs_error_t SrsCompositeBridge::initialize(SrsRequest *r)
|
||||
srs_error_t SrsCompositeBridge::initialize(ISrsRequest *r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsSharedPtrMessage;
|
||||
class SrsLiveSource;
|
||||
class SrsRtcSource;
|
||||
|
|
@ -35,7 +35,7 @@ public:
|
|||
virtual ~ISrsStreamBridge();
|
||||
|
||||
public:
|
||||
virtual srs_error_t initialize(SrsRequest *r) = 0;
|
||||
virtual srs_error_t initialize(ISrsRequest *r) = 0;
|
||||
virtual srs_error_t on_publish() = 0;
|
||||
virtual srs_error_t on_frame(SrsSharedPtrMessage *frame) = 0;
|
||||
virtual void on_unpublish() = 0;
|
||||
|
|
@ -52,7 +52,7 @@ public:
|
|||
virtual ~SrsFrameToRtmpBridge();
|
||||
|
||||
public:
|
||||
srs_error_t initialize(SrsRequest *r);
|
||||
srs_error_t initialize(ISrsRequest *r);
|
||||
|
||||
public:
|
||||
virtual srs_error_t on_publish();
|
||||
|
|
@ -77,7 +77,7 @@ public:
|
|||
virtual ~SrsFrameToRtcBridge();
|
||||
|
||||
public:
|
||||
virtual srs_error_t initialize(SrsRequest *r);
|
||||
virtual srs_error_t initialize(ISrsRequest *r);
|
||||
virtual srs_error_t on_publish();
|
||||
virtual void on_unpublish();
|
||||
virtual srs_error_t on_frame(SrsSharedPtrMessage *frame);
|
||||
|
|
@ -99,7 +99,7 @@ public:
|
|||
virtual ~SrsFrameToRtspBridge();
|
||||
|
||||
public:
|
||||
virtual srs_error_t initialize(SrsRequest *r);
|
||||
virtual srs_error_t initialize(ISrsRequest *r);
|
||||
virtual srs_error_t on_publish();
|
||||
virtual void on_unpublish();
|
||||
virtual srs_error_t on_frame(SrsSharedPtrMessage *frame);
|
||||
|
|
@ -117,7 +117,7 @@ public:
|
|||
public:
|
||||
bool empty() { return bridges_.empty(); } // SrsCompositeBridge::empty()
|
||||
public:
|
||||
srs_error_t initialize(SrsRequest *r);
|
||||
srs_error_t initialize(ISrsRequest *r);
|
||||
|
||||
public:
|
||||
virtual srs_error_t on_publish();
|
||||
|
|
|
|||
|
|
@ -9,6 +9,6 @@
|
|||
|
||||
#define VERSION_MAJOR 7
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 60
|
||||
#define VERSION_REVISION 61
|
||||
|
||||
#endif
|
||||
|
|
@ -661,7 +661,7 @@ private:
|
|||
int64_t raw_aac_dts;
|
||||
|
||||
private:
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
SrsBasicRtmpClient *sdk;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -593,9 +593,9 @@ SrsHttpHeader *SrsHttpMessage::header()
|
|||
return &_header;
|
||||
}
|
||||
|
||||
SrsRequest *SrsHttpMessage::to_request(string vhost)
|
||||
ISrsRequest *SrsHttpMessage::to_request(string vhost)
|
||||
{
|
||||
SrsRequest *req = new SrsRequest();
|
||||
ISrsRequest *req = new SrsRequest();
|
||||
|
||||
// http path, for instance, /live/livestream.flv, parse to
|
||||
// app: /live
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
class ISrsConnection;
|
||||
class SrsFastStream;
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class ISrsReader;
|
||||
class SrsHttpResponseReader;
|
||||
class ISrsProtocolReadWriter;
|
||||
|
|
@ -192,7 +192,7 @@ public:
|
|||
public:
|
||||
// Convert the http message to a request.
|
||||
// @remark user must free the return request.
|
||||
virtual SrsRequest *to_request(std::string vhost);
|
||||
virtual ISrsRequest *to_request(std::string vhost);
|
||||
|
||||
public:
|
||||
virtual bool is_jsonp();
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
class SrsRequest;
|
||||
class ISrsRequest;
|
||||
class SrsTcpClient;
|
||||
class SrsRtmpClient;
|
||||
class SrsCommonMessage;
|
||||
|
|
@ -36,7 +36,7 @@ private:
|
|||
srs_utime_t stream_timeout;
|
||||
|
||||
protected:
|
||||
SrsRequest *req;
|
||||
ISrsRequest *req;
|
||||
|
||||
private:
|
||||
SrsTcpClient *transport;
|
||||
|
|
|
|||
|
|
@ -1459,6 +1459,18 @@ SrsChunkStream::~SrsChunkStream()
|
|||
srs_freep(msg);
|
||||
}
|
||||
|
||||
ISrsRequest::ISrsRequest()
|
||||
{
|
||||
}
|
||||
|
||||
ISrsRequest::~ISrsRequest()
|
||||
{
|
||||
}
|
||||
|
||||
void ISrsRequest::on_source_created()
|
||||
{
|
||||
}
|
||||
|
||||
SrsRequest::SrsRequest()
|
||||
{
|
||||
objectEncoding = RTMP_SIG_AMF0_VER;
|
||||
|
|
@ -1474,7 +1486,7 @@ SrsRequest::~SrsRequest()
|
|||
srs_freep(args);
|
||||
}
|
||||
|
||||
SrsRequest *SrsRequest::copy()
|
||||
ISrsRequest *SrsRequest::copy()
|
||||
{
|
||||
SrsRequest *cp = new SrsRequest();
|
||||
|
||||
|
|
@ -1500,7 +1512,7 @@ SrsRequest *SrsRequest::copy()
|
|||
return cp;
|
||||
}
|
||||
|
||||
void SrsRequest::update_auth(SrsRequest *req)
|
||||
void SrsRequest::update_auth(ISrsRequest *req)
|
||||
{
|
||||
pageUrl = req->pageUrl;
|
||||
swfUrl = req->swfUrl;
|
||||
|
|
@ -1551,7 +1563,7 @@ void SrsRequest::strip()
|
|||
stream = srs_string_trim_start(stream, "/");
|
||||
}
|
||||
|
||||
SrsRequest *SrsRequest::as_http()
|
||||
ISrsRequest *SrsRequest::as_http()
|
||||
{
|
||||
schema = "http";
|
||||
tcUrl = srs_generate_tc_url(schema, host, vhost, app, port);
|
||||
|
|
@ -1883,7 +1895,7 @@ srs_error_t SrsRtmpClient::complex_handshake()
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtmpClient::connect_app(string app, string tcUrl, SrsRequest *r, bool dsu, SrsServerInfo *si)
|
||||
srs_error_t SrsRtmpClient::connect_app(string app, string tcUrl, ISrsRequest *r, bool dsu, SrsServerInfo *si)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -2256,7 +2268,7 @@ srs_error_t SrsRtmpServer::handshake()
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtmpServer::connect_app(SrsRequest *req)
|
||||
srs_error_t SrsRtmpServer::connect_app(ISrsRequest *req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -2331,7 +2343,7 @@ srs_error_t SrsRtmpServer::set_peer_bandwidth(int bandwidth, int type)
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtmpServer::response_connect_app(SrsRequest *req, const char *server_ip)
|
||||
srs_error_t SrsRtmpServer::response_connect_app(ISrsRequest *req, const char *server_ip)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -2372,7 +2384,7 @@ srs_error_t SrsRtmpServer::response_connect_app(SrsRequest *req, const char *ser
|
|||
}
|
||||
|
||||
#define SRS_RTMP_REDIRECT_TIMEOUT (3 * SRS_UTIME_SECONDS)
|
||||
srs_error_t SrsRtmpServer::redirect(SrsRequest *r, string url, bool &accepted)
|
||||
srs_error_t SrsRtmpServer::redirect(ISrsRequest *r, string url, bool &accepted)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
@ -2423,7 +2435,7 @@ srs_error_t SrsRtmpServer::redirect(SrsRequest *r, string url, bool &accepted)
|
|||
return err;
|
||||
}
|
||||
|
||||
void SrsRtmpServer::response_connect_reject(SrsRequest * /*req*/, const char *desc)
|
||||
void SrsRtmpServer::response_connect_reject(ISrsRequest * /*req*/, const char *desc)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
|
|||
|
|
@ -408,8 +408,7 @@ public:
|
|||
virtual ~SrsChunkStream();
|
||||
};
|
||||
|
||||
// The original request from client.
|
||||
class SrsRequest
|
||||
class ISrsRequest
|
||||
{
|
||||
public:
|
||||
// The client ip.
|
||||
|
|
@ -457,34 +456,55 @@ public:
|
|||
// @see https://github.com/ossrs/srs/issues/104
|
||||
SrsAmf0Object *args;
|
||||
|
||||
public:
|
||||
SrsRequest();
|
||||
virtual ~SrsRequest();
|
||||
|
||||
public:
|
||||
// Deep copy the request, for source to use it to support reload,
|
||||
// For when initialize the source, the request is valid,
|
||||
// When reload it, the request maybe invalid, so need to copy it.
|
||||
virtual SrsRequest *copy();
|
||||
// update the auth info of request,
|
||||
// To keep the current request ptr is ok,
|
||||
// For many components use the ptr of request.
|
||||
virtual void update_auth(SrsRequest *req);
|
||||
// Get the stream identify, vhost/app/stream.
|
||||
virtual std::string get_stream_url();
|
||||
// To strip url, user must strip when update the url.
|
||||
virtual void strip();
|
||||
|
||||
public:
|
||||
// Transform it as HTTP request.
|
||||
virtual SrsRequest *as_http();
|
||||
|
||||
public:
|
||||
// The protocol of client:
|
||||
// rtmp, Adobe RTMP protocol.
|
||||
// flv, HTTP-FLV protocol.
|
||||
// flvs, HTTPS-FLV protocol.
|
||||
std::string protocol;
|
||||
|
||||
public:
|
||||
ISrsRequest();
|
||||
virtual ~ISrsRequest();
|
||||
|
||||
public:
|
||||
// Deep copy the request, for source to use it to support reload,
|
||||
// For when initialize the source, the request is valid,
|
||||
// When reload it, the request maybe invalid, so need to copy it.
|
||||
virtual ISrsRequest *copy() = 0;
|
||||
// update the auth info of request,
|
||||
// To keep the current request ptr is ok,
|
||||
// For many components use the ptr of request.
|
||||
virtual void update_auth(ISrsRequest *req) = 0;
|
||||
// Get the stream identify, vhost/app/stream.
|
||||
virtual std::string get_stream_url() = 0;
|
||||
// To strip url, user must strip when update the url.
|
||||
virtual void strip() = 0;
|
||||
|
||||
public:
|
||||
// Transform it as HTTP request.
|
||||
virtual ISrsRequest *as_http() = 0;
|
||||
|
||||
public:
|
||||
// Callback when source is created.
|
||||
virtual void on_source_created();
|
||||
};
|
||||
|
||||
// The original request from client.
|
||||
class SrsRequest : public ISrsRequest
|
||||
{
|
||||
public:
|
||||
SrsRequest();
|
||||
virtual ~SrsRequest();
|
||||
|
||||
public:
|
||||
virtual ISrsRequest *copy();
|
||||
virtual void update_auth(ISrsRequest *req);
|
||||
virtual std::string get_stream_url();
|
||||
virtual void strip();
|
||||
|
||||
public:
|
||||
virtual ISrsRequest *as_http();
|
||||
};
|
||||
|
||||
// The response to client.
|
||||
|
|
@ -601,7 +621,7 @@ public:
|
|||
// @param req, the optional req object, use the swfUrl/pageUrl if specified. NULL to ignore.
|
||||
// @param dsu, Whether debug SRS upnode. For edge, set to true to send its info to upnode.
|
||||
// @param si, The server information, retrieve from response of connect app request. NULL to ignore.
|
||||
virtual srs_error_t connect_app(std::string app, std::string tcUrl, SrsRequest *r, bool dsu, SrsServerInfo *si);
|
||||
virtual srs_error_t connect_app(std::string app, std::string tcUrl, ISrsRequest *r, bool dsu, SrsServerInfo *si);
|
||||
// Create a stream, then play/publish data over this stream.
|
||||
virtual srs_error_t create_stream(int &stream_id);
|
||||
// start play stream.
|
||||
|
|
@ -722,7 +742,7 @@ public:
|
|||
// Do handshake with client, try complex then simple.
|
||||
virtual srs_error_t handshake();
|
||||
// Do connect app with client, to discovery tcUrl.
|
||||
virtual srs_error_t connect_app(SrsRequest *req);
|
||||
virtual srs_error_t connect_app(ISrsRequest *req);
|
||||
// Set output ack size to client, client will send ack-size for each ack window
|
||||
virtual srs_error_t set_window_ack_size(int ack_size);
|
||||
// Set the default input ack size value.
|
||||
|
|
@ -731,13 +751,13 @@ public:
|
|||
// using the Limit type field.
|
||||
virtual srs_error_t set_peer_bandwidth(int bandwidth, int type);
|
||||
// @param server_ip the ip of server.
|
||||
virtual srs_error_t response_connect_app(SrsRequest *req, const char *server_ip = NULL);
|
||||
virtual srs_error_t response_connect_app(ISrsRequest *req, const char *server_ip = NULL);
|
||||
// Redirect the connection to another rtmp server.
|
||||
// @param a RTMP url to redirect to.
|
||||
// @param whether the client accept the redirect.
|
||||
virtual srs_error_t redirect(SrsRequest *r, std::string url, bool &accepted);
|
||||
virtual srs_error_t redirect(ISrsRequest *r, std::string url, bool &accepted);
|
||||
// Reject the connect app request.
|
||||
virtual void response_connect_reject(SrsRequest *req, const char *desc);
|
||||
virtual void response_connect_reject(ISrsRequest *req, const char *desc);
|
||||
// Response client the onBWDone message.
|
||||
virtual srs_error_t on_bw_done();
|
||||
// Recv some message to identify the client.
|
||||
|
|
|
|||
|
|
@ -976,7 +976,7 @@ VOID TEST(ProtocolRTMPTest, RecvMessage3)
|
|||
SrsRequest req;
|
||||
req.ip = "10.11.12.13";
|
||||
|
||||
SrsRequest *cp = req.copy();
|
||||
ISrsRequest *cp = req.copy();
|
||||
EXPECT_STREQ("10.11.12.13", cp->ip.c_str());
|
||||
srs_freep(cp);
|
||||
}
|
||||
|
|
@ -989,7 +989,7 @@ VOID TEST(ProtocolRTMPTest, RecvMessage3)
|
|||
obj->set("id", SrsAmf0Any::str("srs"));
|
||||
req.args = obj;
|
||||
|
||||
SrsRequest *cp = req.copy();
|
||||
ISrsRequest *cp = req.copy();
|
||||
EXPECT_STREQ("10.11.12.13", cp->ip.c_str());
|
||||
|
||||
SrsAmf0Object *cpa = dynamic_cast<SrsAmf0Object *>(cp->args);
|
||||
|
|
|
|||
|
|
@ -636,7 +636,7 @@ VOID TEST(HTTPServerTest, MessageTurnRequest)
|
|||
if (true) {
|
||||
SrsHttpMessage m;
|
||||
HELPER_ASSERT_SUCCESS(m.set_url("http://127.0.0.1/live/livestream.flv", false));
|
||||
SrsRequest *r = m.to_request("ossrs.net");
|
||||
ISrsRequest *r = m.to_request("ossrs.net");
|
||||
EXPECT_STREQ("live", r->app.c_str());
|
||||
EXPECT_STREQ("livestream", r->stream.c_str());
|
||||
EXPECT_STREQ("rtmp://ossrs.net/live", r->tcUrl.c_str());
|
||||
|
|
@ -646,7 +646,7 @@ VOID TEST(HTTPServerTest, MessageTurnRequest)
|
|||
if (true) {
|
||||
SrsHttpMessage m;
|
||||
HELPER_ASSERT_SUCCESS(m.set_url("http://127.0.0.1/live/livestream.flv?token=key", false));
|
||||
SrsRequest *r = m.to_request("ossrs.net");
|
||||
ISrsRequest *r = m.to_request("ossrs.net");
|
||||
EXPECT_STREQ("rtmp://ossrs.net/live", r->tcUrl.c_str());
|
||||
EXPECT_STREQ("?token=key", r->param.c_str());
|
||||
srs_freep(r);
|
||||
|
|
@ -657,7 +657,7 @@ VOID TEST(HTTPServerTest, MessageTurnRequest)
|
|||
SrsHttpMessage m;
|
||||
m.set_connection(&conn);
|
||||
|
||||
SrsRequest *r = m.to_request("ossrs.net");
|
||||
ISrsRequest *r = m.to_request("ossrs.net");
|
||||
EXPECT_STREQ("127.0.0.1", r->ip.c_str());
|
||||
srs_freep(r);
|
||||
}
|
||||
|
|
@ -671,7 +671,7 @@ VOID TEST(HTTPServerTest, MessageTurnRequest)
|
|||
hdr.set("X-Real-IP", "10.11.12.13");
|
||||
m.set_header(&hdr, false);
|
||||
|
||||
SrsRequest *r = m.to_request("ossrs.net");
|
||||
ISrsRequest *r = m.to_request("ossrs.net");
|
||||
EXPECT_STREQ("10.11.12.13", r->ip.c_str());
|
||||
srs_freep(r);
|
||||
}
|
||||
|
|
|
|||
817
trunk/src/utest/srs_utest_source_lock.cpp
Normal file
817
trunk/src/utest/srs_utest_source_lock.cpp
Normal file
|
|
@ -0,0 +1,817 @@
|
|||
//
|
||||
// Copyright (c) 2013-2025 The SRS Authors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
#include <srs_utest_source_lock.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <srs_app_config.hpp>
|
||||
#include <srs_app_rtc_source.hpp>
|
||||
#include <srs_app_server.hpp>
|
||||
#include <srs_app_source.hpp>
|
||||
#include <srs_app_srt_source.hpp>
|
||||
#include <srs_kernel_error.hpp>
|
||||
#include <srs_protocol_amf0.hpp>
|
||||
#include <srs_protocol_rtmp_stack.hpp>
|
||||
#include <srs_protocol_st.hpp>
|
||||
#include <st.h>
|
||||
#ifdef SRS_RTSP
|
||||
#include <srs_app_rtsp_source.hpp>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Unit tests for source lock refinement (PR #4449)
|
||||
*
|
||||
* This file tests the race condition fixes in source managers where multiple
|
||||
* coroutines could create duplicate sources for the same stream. The fix ensures
|
||||
* atomic source creation and pool insertion.
|
||||
*
|
||||
* Template Design:
|
||||
* - MockOtherSourceAsyncCreator<ManagerType, SourceType>: Template for RTC, SRT, RTSP
|
||||
* - MockLiveSourceAsyncCreator: Separate class for Live sources (needs handler parameter)
|
||||
* - Type aliases provide backward compatibility with original class names
|
||||
*/
|
||||
|
||||
// This mock request always cause context switch in get_stream_url().
|
||||
class MockAsyncSrsRequest : public ISrsRequest
|
||||
{
|
||||
public:
|
||||
string mock_stream_url;
|
||||
bool enable_context_switch;
|
||||
|
||||
MockAsyncSrsRequest(const string &url = "/live/livestream", bool context_switch = false)
|
||||
{
|
||||
mock_stream_url = url;
|
||||
enable_context_switch = context_switch;
|
||||
|
||||
// Initialize all ISrsRequest members to safe defaults
|
||||
objectEncoding = RTMP_SIG_AMF0_VER;
|
||||
duration = -1;
|
||||
port = SRS_CONSTS_RTMP_DEFAULT_PORT;
|
||||
args = NULL; // Initialize to NULL to prevent crashes
|
||||
protocol = "rtmp";
|
||||
|
||||
// Parse the URL to set vhost, app, stream
|
||||
size_t app_pos = url.find('/', 1); // Find second slash
|
||||
if (app_pos != string::npos) {
|
||||
size_t stream_pos = url.find('/', app_pos + 1); // Find third slash
|
||||
if (stream_pos != string::npos) {
|
||||
app = url.substr(app_pos + 1, stream_pos - app_pos - 1);
|
||||
stream = url.substr(stream_pos + 1);
|
||||
} else {
|
||||
app = url.substr(app_pos + 1);
|
||||
stream = "livestream";
|
||||
}
|
||||
} else {
|
||||
app = "live";
|
||||
stream = "livestream";
|
||||
}
|
||||
|
||||
vhost = "localhost";
|
||||
}
|
||||
|
||||
virtual string get_stream_url()
|
||||
{
|
||||
on_source_created();
|
||||
return mock_stream_url;
|
||||
}
|
||||
|
||||
virtual void on_source_created()
|
||||
{
|
||||
// Simulate context switch that could happen during source initialization
|
||||
if (enable_context_switch) {
|
||||
// Force a context switch by yielding to other coroutines
|
||||
// This simulates the original race condition scenario
|
||||
st_usleep(1 * SRS_UTIME_MILLISECONDS); // 1ms sleep to trigger context switch
|
||||
}
|
||||
}
|
||||
|
||||
virtual ISrsRequest *copy()
|
||||
{
|
||||
MockAsyncSrsRequest *cp = new MockAsyncSrsRequest(mock_stream_url, enable_context_switch);
|
||||
|
||||
*cp = *this;
|
||||
if (args) {
|
||||
cp->args = args->copy()->to_object();
|
||||
}
|
||||
|
||||
return cp;
|
||||
}
|
||||
|
||||
virtual void update_auth(ISrsRequest *req)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void strip()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ISrsRequest *as_http()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
// Template for non-live source async creators (RTC, SRT, RTSP)
|
||||
// Since SRS uses C++98, we use a simple template approach
|
||||
// Note: MockLiveSourceAsyncCreator is kept separate because it requires an additional
|
||||
// ISrsLiveSourceHandler parameter that the other source managers don't need
|
||||
template <typename ManagerType, typename SourceType>
|
||||
class MockOtherSourceAsyncCreator : public ISrsCoroutineHandler
|
||||
{
|
||||
public:
|
||||
SrsWaitGroup *wg_;
|
||||
ManagerType *manager_;
|
||||
MockAsyncSrsRequest *req_;
|
||||
SrsSharedPtr<SourceType> source_;
|
||||
|
||||
MockOtherSourceAsyncCreator(SrsWaitGroup *w, ManagerType *m, MockAsyncSrsRequest *r)
|
||||
{
|
||||
wg_ = w;
|
||||
manager_ = m;
|
||||
req_ = r;
|
||||
}
|
||||
|
||||
virtual ~MockOtherSourceAsyncCreator()
|
||||
{
|
||||
}
|
||||
|
||||
virtual srs_error_t cycle()
|
||||
{
|
||||
srs_error_t err = do_cycle();
|
||||
wg_->done();
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t do_cycle()
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// Test fetch_or_create - should create new source
|
||||
if ((err = manager_->fetch_or_create(req_, source_)) != srs_success) {
|
||||
return srs_error_wrap(err, "fetch or create");
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
};
|
||||
|
||||
// Type aliases for convenience (C++98 compatible)
|
||||
typedef MockOtherSourceAsyncCreator<SrsLiveSourceManager, SrsLiveSource> MockLiveSourceAsyncCreator;
|
||||
|
||||
// Test race condition of source managers
|
||||
VOID TEST(SourceLockTest, LiveSourceManager_RaceCondition)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
SrsLiveSourceManager manager;
|
||||
HELPER_EXPECT_SUCCESS(manager.initialize());
|
||||
|
||||
MockAsyncSrsRequest req("/live/test1", true); // Enable context switch
|
||||
SrsSharedPtr<SrsLiveSource> source;
|
||||
|
||||
// Create a coroutine to create source2.
|
||||
SrsWaitGroup wg;
|
||||
MockLiveSourceAsyncCreator creator(&wg, &manager, &req);
|
||||
SrsSTCoroutine trd("test", &creator);
|
||||
|
||||
wg.add(1);
|
||||
HELPER_EXPECT_SUCCESS(trd.start());
|
||||
|
||||
// Test fetch_or_create - should create new source
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source));
|
||||
EXPECT_TRUE(source.get() != NULL);
|
||||
|
||||
// Wait for coroutine to finish.
|
||||
wg.wait();
|
||||
|
||||
// The created two sources should be the same instance (no duplicates created)
|
||||
EXPECT_EQ(source.get(), creator.source_.get());
|
||||
|
||||
// Test fetch - should return the same source
|
||||
SrsSharedPtr<SrsLiveSource> fetched = manager.fetch(&req);
|
||||
EXPECT_TRUE(fetched.get() != NULL);
|
||||
EXPECT_EQ(source.get(), fetched.get());
|
||||
|
||||
// Test fetch_or_create again - should return existing source
|
||||
SrsSharedPtr<SrsLiveSource> source2;
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source2));
|
||||
EXPECT_EQ(source.get(), source2.get());
|
||||
}
|
||||
|
||||
// Type aliases for convenience (C++98 compatible)
|
||||
typedef MockOtherSourceAsyncCreator<SrsRtcSourceManager, SrsRtcSource> MockRtcSourceAsyncCreator;
|
||||
|
||||
// Test race condition of source managers
|
||||
VOID TEST(SourceLockTest, RtcSourceManager_RaceCondition)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
SrsRtcSourceManager manager;
|
||||
HELPER_EXPECT_SUCCESS(manager.initialize());
|
||||
|
||||
MockAsyncSrsRequest req("/live/test1", true); // Enable context switch
|
||||
SrsSharedPtr<SrsRtcSource> source;
|
||||
|
||||
// Create a coroutine to create source2.
|
||||
SrsWaitGroup wg;
|
||||
MockRtcSourceAsyncCreator creator(&wg, &manager, &req);
|
||||
SrsSTCoroutine trd("test", &creator);
|
||||
|
||||
wg.add(1);
|
||||
HELPER_EXPECT_SUCCESS(trd.start());
|
||||
|
||||
// Test fetch_or_create - should create new source
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source));
|
||||
EXPECT_TRUE(source.get() != NULL);
|
||||
|
||||
// Wait for coroutine to finish.
|
||||
wg.wait();
|
||||
|
||||
// The created two sources should be the same instance (no duplicates created)
|
||||
EXPECT_EQ(source.get(), creator.source_.get());
|
||||
|
||||
// Test fetch - should return the same source
|
||||
SrsSharedPtr<SrsRtcSource> fetched = manager.fetch(&req);
|
||||
EXPECT_TRUE(fetched.get() != NULL);
|
||||
EXPECT_EQ(source.get(), fetched.get());
|
||||
|
||||
// Test fetch_or_create again - should return existing source
|
||||
SrsSharedPtr<SrsRtcSource> source2;
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source2));
|
||||
EXPECT_EQ(source.get(), source2.get());
|
||||
}
|
||||
|
||||
typedef MockOtherSourceAsyncCreator<SrsSrtSourceManager, SrsSrtSource> MockSrtSourceAsyncCreator;
|
||||
|
||||
// Test race condition of source managers
|
||||
VOID TEST(SourceLockTest, SrtSourceManager_RaceCondition)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
SrsSrtSourceManager manager;
|
||||
HELPER_EXPECT_SUCCESS(manager.initialize());
|
||||
|
||||
MockAsyncSrsRequest req("/live/test1", true); // Enable context switch
|
||||
SrsSharedPtr<SrsSrtSource> source;
|
||||
|
||||
// Create a coroutine to create source2.
|
||||
SrsWaitGroup wg;
|
||||
MockSrtSourceAsyncCreator creator(&wg, &manager, &req);
|
||||
SrsSTCoroutine trd("test", &creator);
|
||||
|
||||
wg.add(1);
|
||||
HELPER_EXPECT_SUCCESS(trd.start());
|
||||
|
||||
// Test fetch_or_create - should create new source
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source));
|
||||
EXPECT_TRUE(source.get() != NULL);
|
||||
|
||||
// Wait for coroutine to finish.
|
||||
wg.wait();
|
||||
|
||||
// The created two sources should be the same instance (no duplicates created)
|
||||
EXPECT_EQ(source.get(), creator.source_.get());
|
||||
|
||||
// Test fetch - should return the same source
|
||||
SrsSharedPtr<SrsSrtSource> fetched = manager.fetch(&req);
|
||||
EXPECT_TRUE(fetched.get() != NULL);
|
||||
EXPECT_EQ(source.get(), fetched.get());
|
||||
|
||||
// Test fetch_or_create again - should return existing source
|
||||
SrsSharedPtr<SrsSrtSource> source2;
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source2));
|
||||
EXPECT_EQ(source.get(), source2.get());
|
||||
}
|
||||
|
||||
// Test basic functionality of source managers
|
||||
VOID TEST(SourceLockTest, LiveSourceManager_BasicFunctionality)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
SrsLiveSourceManager manager;
|
||||
HELPER_EXPECT_SUCCESS(manager.initialize());
|
||||
|
||||
MockAsyncSrsRequest req("/live/test1");
|
||||
SrsSharedPtr<SrsLiveSource> source;
|
||||
|
||||
// Test fetch_or_create - should create new source
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source));
|
||||
EXPECT_TRUE(source.get() != NULL);
|
||||
|
||||
// Test fetch - should return the same source
|
||||
SrsSharedPtr<SrsLiveSource> fetched = manager.fetch(&req);
|
||||
EXPECT_TRUE(fetched.get() != NULL);
|
||||
EXPECT_EQ(source.get(), fetched.get());
|
||||
|
||||
// Test fetch_or_create again - should return existing source
|
||||
SrsSharedPtr<SrsLiveSource> source2;
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source2));
|
||||
EXPECT_EQ(source.get(), source2.get());
|
||||
}
|
||||
|
||||
// Test concurrent access scenarios to verify race condition fixes
|
||||
VOID TEST(SourceLockTest, LiveSourceManager_ConcurrentAccess)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
SrsLiveSourceManager manager;
|
||||
HELPER_EXPECT_SUCCESS(manager.initialize());
|
||||
|
||||
MockAsyncSrsRequest req("/live/concurrent_test", true); // Enable context switch
|
||||
|
||||
// Simulate multiple concurrent requests for the same stream
|
||||
vector<SrsSharedPtr<SrsLiveSource> > sources;
|
||||
const int concurrent_requests = 10;
|
||||
|
||||
for (int i = 0; i < concurrent_requests; i++) {
|
||||
SrsSharedPtr<SrsLiveSource> source;
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source));
|
||||
sources.push_back(source);
|
||||
EXPECT_TRUE(source.get() != NULL);
|
||||
}
|
||||
|
||||
// All sources should be the same instance (no duplicates created)
|
||||
for (int i = 1; i < concurrent_requests; i++) {
|
||||
EXPECT_EQ(sources[0].get(), sources[i].get());
|
||||
}
|
||||
}
|
||||
|
||||
// Test different stream URLs create different sources
|
||||
VOID TEST(SourceLockTest, LiveSourceManager_DifferentStreams)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
SrsLiveSourceManager manager;
|
||||
HELPER_EXPECT_SUCCESS(manager.initialize());
|
||||
|
||||
// Create sources for different streams
|
||||
MockAsyncSrsRequest req1("/live/stream1");
|
||||
MockAsyncSrsRequest req2("/live/stream2");
|
||||
MockAsyncSrsRequest req3("/live/stream3");
|
||||
|
||||
SrsSharedPtr<SrsLiveSource> source1, source2, source3;
|
||||
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req1, source1));
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req2, source2));
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req3, source3));
|
||||
|
||||
// All sources should be different instances
|
||||
EXPECT_TRUE(source1.get() != NULL);
|
||||
EXPECT_TRUE(source2.get() != NULL);
|
||||
EXPECT_TRUE(source3.get() != NULL);
|
||||
EXPECT_NE(source1.get(), source2.get());
|
||||
EXPECT_NE(source1.get(), source3.get());
|
||||
EXPECT_NE(source2.get(), source3.get());
|
||||
|
||||
// Fetch should return the same sources
|
||||
SrsSharedPtr<SrsLiveSource> fetched1 = manager.fetch(&req1);
|
||||
SrsSharedPtr<SrsLiveSource> fetched2 = manager.fetch(&req2);
|
||||
SrsSharedPtr<SrsLiveSource> fetched3 = manager.fetch(&req3);
|
||||
|
||||
EXPECT_EQ(source1.get(), fetched1.get());
|
||||
EXPECT_EQ(source2.get(), fetched2.get());
|
||||
EXPECT_EQ(source3.get(), fetched3.get());
|
||||
}
|
||||
|
||||
// Test fetch for non-existent stream returns NULL
|
||||
VOID TEST(SourceLockTest, LiveSourceManager_FetchNonExistent)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
SrsLiveSourceManager manager;
|
||||
HELPER_EXPECT_SUCCESS(manager.initialize());
|
||||
|
||||
MockAsyncSrsRequest req("/live/nonexistent");
|
||||
|
||||
// Fetch non-existent source should return NULL
|
||||
SrsSharedPtr<SrsLiveSource> source = manager.fetch(&req);
|
||||
EXPECT_TRUE(source.get() == NULL);
|
||||
}
|
||||
|
||||
// Test that created flag works correctly for initialization
|
||||
VOID TEST(SourceLockTest, LiveSourceManager_CreatedFlagLogic)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
SrsLiveSourceManager manager;
|
||||
HELPER_EXPECT_SUCCESS(manager.initialize());
|
||||
|
||||
MockAsyncSrsRequest req("/live/created_flag_test");
|
||||
|
||||
// First call should create and initialize
|
||||
SrsSharedPtr<SrsLiveSource> source1;
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source1));
|
||||
EXPECT_TRUE(source1.get() != NULL);
|
||||
|
||||
// Second call should find existing and only update auth (not initialize again)
|
||||
SrsSharedPtr<SrsLiveSource> source2;
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source2));
|
||||
EXPECT_EQ(source1.get(), source2.get());
|
||||
}
|
||||
|
||||
// Test lock protection during source creation
|
||||
VOID TEST(SourceLockTest, LiveSourceManager_LockProtection)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
// Test that the lock scope is properly limited
|
||||
// This test verifies that no functions are called during locking
|
||||
|
||||
SrsLiveSourceManager live_manager;
|
||||
HELPER_EXPECT_SUCCESS(live_manager.initialize());
|
||||
|
||||
SrsRtcSourceManager rtc_manager;
|
||||
HELPER_EXPECT_SUCCESS(rtc_manager.initialize());
|
||||
|
||||
SrsSrtSourceManager srt_manager;
|
||||
HELPER_EXPECT_SUCCESS(srt_manager.initialize());
|
||||
|
||||
// Test that managers can handle rapid successive calls
|
||||
MockAsyncSrsRequest req("/live/lock_test");
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
SrsSharedPtr<SrsLiveSource> live_source;
|
||||
HELPER_EXPECT_SUCCESS(live_manager.fetch_or_create(&req, live_source));
|
||||
EXPECT_TRUE(live_source.get() != NULL);
|
||||
|
||||
SrsSharedPtr<SrsRtcSource> rtc_source;
|
||||
HELPER_EXPECT_SUCCESS(rtc_manager.fetch_or_create(&req, rtc_source));
|
||||
EXPECT_TRUE(rtc_source.get() != NULL);
|
||||
|
||||
SrsSharedPtr<SrsSrtSource> srt_source;
|
||||
HELPER_EXPECT_SUCCESS(srt_manager.fetch_or_create(&req, srt_source));
|
||||
EXPECT_TRUE(srt_source.get() != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// Test that simulates the original race condition scenario from issue #1230
|
||||
// This test verifies that the fix prevents multiple sources for the same stream
|
||||
VOID TEST(SourceLockTest, LiveSourceManager_RaceConditionPrevention_Issue1230)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
SrsLiveSourceManager manager;
|
||||
HELPER_EXPECT_SUCCESS(manager.initialize());
|
||||
|
||||
MockAsyncSrsRequest req("/live/race_condition_test", true); // Enable context switch
|
||||
|
||||
// Simulate the scenario where multiple coroutines try to create
|
||||
// sources for the same stream simultaneously
|
||||
vector<SrsSharedPtr<SrsLiveSource> > sources;
|
||||
const int num_attempts = 20;
|
||||
|
||||
// This simulates what would happen if multiple coroutines
|
||||
// called fetch_or_create simultaneously before the fix
|
||||
for (int i = 0; i < num_attempts; i++) {
|
||||
SrsSharedPtr<SrsLiveSource> source;
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source));
|
||||
sources.push_back(source);
|
||||
|
||||
// Verify source is valid
|
||||
EXPECT_TRUE(source.get() != NULL);
|
||||
|
||||
// Verify it's the same source every time (no duplicates)
|
||||
if (i > 0) {
|
||||
EXPECT_EQ(sources[0].get(), source.get())
|
||||
<< "Race condition detected: different source instances created for same stream";
|
||||
}
|
||||
}
|
||||
|
||||
// Double-check that all sources are identical
|
||||
for (int i = 1; i < num_attempts; i++) {
|
||||
EXPECT_EQ(sources[0].get(), sources[i].get())
|
||||
<< "Source " << i << " differs from source 0";
|
||||
}
|
||||
|
||||
// Verify fetch also returns the same source
|
||||
SrsSharedPtr<SrsLiveSource> fetched = manager.fetch(&req);
|
||||
EXPECT_EQ(sources[0].get(), fetched.get());
|
||||
}
|
||||
|
||||
// Test the atomic nature of source creation and pool insertion
|
||||
VOID TEST(SourceLockTest, LiveSourceManager_AtomicSourceCreation)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
// Test all source manager types
|
||||
SrsRtcSourceManager rtc_manager;
|
||||
HELPER_EXPECT_SUCCESS(rtc_manager.initialize());
|
||||
|
||||
SrsSrtSourceManager srt_manager;
|
||||
HELPER_EXPECT_SUCCESS(srt_manager.initialize());
|
||||
|
||||
MockAsyncSrsRequest req("/live/atomic_test", true); // Enable context switch
|
||||
|
||||
// Test RTC source manager
|
||||
vector<SrsSharedPtr<SrsRtcSource> > rtc_sources;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
SrsSharedPtr<SrsRtcSource> source;
|
||||
HELPER_EXPECT_SUCCESS(rtc_manager.fetch_or_create(&req, source));
|
||||
rtc_sources.push_back(source);
|
||||
EXPECT_TRUE(source.get() != NULL);
|
||||
if (i > 0) {
|
||||
EXPECT_EQ(rtc_sources[0].get(), source.get());
|
||||
}
|
||||
}
|
||||
|
||||
// Test SRT source manager
|
||||
vector<SrsSharedPtr<SrsSrtSource> > srt_sources;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
SrsSharedPtr<SrsSrtSource> source;
|
||||
HELPER_EXPECT_SUCCESS(srt_manager.fetch_or_create(&req, source));
|
||||
srt_sources.push_back(source);
|
||||
EXPECT_TRUE(source.get() != NULL);
|
||||
if (i > 0) {
|
||||
EXPECT_EQ(srt_sources[0].get(), source.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test that verifies the fix addresses the specific issue mentioned in #1230
|
||||
// where DVR and HLS module initialization could cause coroutine switches
|
||||
VOID TEST(SourceLockTest, LiveSourceManager_CoroutineSwitchProtection)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
SrsLiveSourceManager manager;
|
||||
HELPER_EXPECT_SUCCESS(manager.initialize());
|
||||
|
||||
// Test multiple streams to ensure each gets its own source
|
||||
vector<string> stream_urls;
|
||||
stream_urls.push_back("/live/dvr_test1");
|
||||
stream_urls.push_back("/live/dvr_test2");
|
||||
stream_urls.push_back("/live/hls_test1");
|
||||
stream_urls.push_back("/live/hls_test2");
|
||||
stream_urls.push_back("/live/mixed_test");
|
||||
|
||||
map<string, SrsSharedPtr<SrsLiveSource> > created_sources;
|
||||
|
||||
// Create sources for each stream
|
||||
for (size_t idx = 0; idx < stream_urls.size(); idx++) {
|
||||
const string &url = stream_urls[idx];
|
||||
MockAsyncSrsRequest req(url, true); // Enable context switch
|
||||
SrsSharedPtr<SrsLiveSource> source;
|
||||
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source));
|
||||
EXPECT_TRUE(source.get() != NULL);
|
||||
|
||||
created_sources[url] = source;
|
||||
|
||||
// Verify subsequent calls return the same source
|
||||
for (int i = 0; i < 3; i++) {
|
||||
SrsSharedPtr<SrsLiveSource> same_source;
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, same_source));
|
||||
EXPECT_EQ(source.get(), same_source.get())
|
||||
<< "Source changed for stream " << url << " on attempt " << i;
|
||||
}
|
||||
}
|
||||
|
||||
// Verify all sources are different from each other
|
||||
vector<SrsLiveSource *> source_ptrs;
|
||||
for (map<string, SrsSharedPtr<SrsLiveSource> >::iterator it = created_sources.begin();
|
||||
it != created_sources.end(); ++it) {
|
||||
source_ptrs.push_back(it->second.get());
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < source_ptrs.size(); i++) {
|
||||
for (size_t j = i + 1; j < source_ptrs.size(); j++) {
|
||||
EXPECT_NE(source_ptrs[i], source_ptrs[j])
|
||||
<< "Sources for different streams should be different instances";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test edge case with empty or invalid stream URLs
|
||||
VOID TEST(SourceLockTest, LiveSourceManager_EdgeCases_InvalidUrls)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
SrsLiveSourceManager manager;
|
||||
HELPER_EXPECT_SUCCESS(manager.initialize());
|
||||
|
||||
// Test with various edge case URLs
|
||||
vector<string> edge_case_urls;
|
||||
edge_case_urls.push_back(""); // Empty URL
|
||||
edge_case_urls.push_back("/"); // Root only
|
||||
edge_case_urls.push_back("/live/"); // Trailing slash
|
||||
edge_case_urls.push_back("/live//"); // Double slash
|
||||
edge_case_urls.push_back("/live/test?param=value"); // With parameters
|
||||
|
||||
for (size_t idx = 0; idx < edge_case_urls.size(); idx++) {
|
||||
const string &url = edge_case_urls[idx];
|
||||
MockAsyncSrsRequest req(url);
|
||||
SrsSharedPtr<SrsLiveSource> source;
|
||||
|
||||
// Should handle edge cases gracefully
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source));
|
||||
EXPECT_TRUE(source.get() != NULL);
|
||||
|
||||
// Verify consistency
|
||||
SrsSharedPtr<SrsLiveSource> source2;
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source2));
|
||||
EXPECT_EQ(source.get(), source2.get());
|
||||
}
|
||||
}
|
||||
|
||||
VOID TEST(SourceLockTest, RtcSourceManager_BasicFunctionality)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
SrsRtcSourceManager manager;
|
||||
HELPER_EXPECT_SUCCESS(manager.initialize());
|
||||
|
||||
MockAsyncSrsRequest req("/live/test2");
|
||||
SrsSharedPtr<SrsRtcSource> source;
|
||||
|
||||
// Test fetch_or_create - should create new source
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source));
|
||||
EXPECT_TRUE(source.get() != NULL);
|
||||
|
||||
// Test fetch - should return the same source
|
||||
SrsSharedPtr<SrsRtcSource> fetched = manager.fetch(&req);
|
||||
EXPECT_TRUE(fetched.get() != NULL);
|
||||
EXPECT_EQ(source.get(), fetched.get());
|
||||
|
||||
// Test fetch_or_create again - should return existing source
|
||||
SrsSharedPtr<SrsRtcSource> source2;
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source2));
|
||||
EXPECT_EQ(source.get(), source2.get());
|
||||
}
|
||||
|
||||
VOID TEST(SourceLockTest, SrtSourceManager_BasicFunctionality)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
SrsSrtSourceManager manager;
|
||||
HELPER_EXPECT_SUCCESS(manager.initialize());
|
||||
|
||||
MockAsyncSrsRequest req("/live/test4");
|
||||
SrsSharedPtr<SrsSrtSource> source;
|
||||
|
||||
// Test fetch_or_create - should create new source
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source));
|
||||
EXPECT_TRUE(source.get() != NULL);
|
||||
|
||||
// Note: SrsSrtSourceManager doesn't have a fetch method, only fetch_or_create
|
||||
// Test fetch_or_create again - should return existing source
|
||||
SrsSharedPtr<SrsSrtSource> source2;
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source2));
|
||||
EXPECT_EQ(source.get(), source2.get());
|
||||
}
|
||||
|
||||
VOID TEST(SourceLockTest, RtcSourceManager_ConcurrentAccess)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
SrsRtcSourceManager manager;
|
||||
HELPER_EXPECT_SUCCESS(manager.initialize());
|
||||
|
||||
MockAsyncSrsRequest req("/live/rtc_concurrent_test", true); // Enable context switch
|
||||
|
||||
// Simulate multiple concurrent requests for the same stream
|
||||
vector<SrsSharedPtr<SrsRtcSource> > sources;
|
||||
const int concurrent_requests = 10;
|
||||
|
||||
for (int i = 0; i < concurrent_requests; i++) {
|
||||
SrsSharedPtr<SrsRtcSource> source;
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source));
|
||||
sources.push_back(source);
|
||||
EXPECT_TRUE(source.get() != NULL);
|
||||
}
|
||||
|
||||
// All sources should be the same instance (no duplicates created)
|
||||
for (int i = 1; i < concurrent_requests; i++) {
|
||||
EXPECT_EQ(sources[0].get(), sources[i].get());
|
||||
}
|
||||
}
|
||||
|
||||
VOID TEST(SourceLockTest, RtcSourceManager_FetchNonExistent)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
SrsRtcSourceManager manager;
|
||||
HELPER_EXPECT_SUCCESS(manager.initialize());
|
||||
|
||||
MockAsyncSrsRequest req("/live/nonexistent");
|
||||
|
||||
// Fetch non-existent source should return NULL
|
||||
SrsSharedPtr<SrsRtcSource> source = manager.fetch(&req);
|
||||
EXPECT_TRUE(source.get() == NULL);
|
||||
}
|
||||
|
||||
#ifdef SRS_RTSP
|
||||
typedef MockOtherSourceAsyncCreator<SrsRtspSourceManager, SrsRtspSource> MockRtspSourceAsyncCreator;
|
||||
|
||||
// Test race condition of source managers
|
||||
VOID TEST(SourceLockTest, RtspSourceManager_RaceCondition)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
SrsRtspSourceManager manager;
|
||||
HELPER_EXPECT_SUCCESS(manager.initialize());
|
||||
|
||||
MockAsyncSrsRequest req("/live/test1", true); // Enable context switch
|
||||
SrsSharedPtr<SrsRtspSource> source;
|
||||
|
||||
// Create a coroutine to create source2.
|
||||
SrsWaitGroup wg;
|
||||
MockRtspSourceAsyncCreator creator(&wg, &manager, &req);
|
||||
SrsSTCoroutine trd("test", &creator);
|
||||
|
||||
wg.add(1);
|
||||
HELPER_EXPECT_SUCCESS(trd.start());
|
||||
|
||||
// Test fetch_or_create - should create new source
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source));
|
||||
EXPECT_TRUE(source.get() != NULL);
|
||||
|
||||
// Wait for coroutine to finish.
|
||||
wg.wait();
|
||||
|
||||
// The created two sources should be the same instance (no duplicates created)
|
||||
EXPECT_EQ(source.get(), creator.source_.get());
|
||||
|
||||
// Test fetch - should return the same source
|
||||
SrsSharedPtr<SrsRtspSource> fetched = manager.fetch(&req);
|
||||
EXPECT_TRUE(fetched.get() != NULL);
|
||||
EXPECT_EQ(source.get(), fetched.get());
|
||||
|
||||
// Test fetch_or_create again - should return existing source
|
||||
SrsSharedPtr<SrsRtspSource> source2;
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source2));
|
||||
EXPECT_EQ(source.get(), source2.get());
|
||||
}
|
||||
|
||||
// Test lock protection during source creation
|
||||
VOID TEST(SourceLockTest, LiveSourceManager_LockProtection2)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
// Test that the lock scope is properly limited
|
||||
// This test verifies that no functions are called during locking
|
||||
|
||||
SrsRtspSourceManager rtsp_manager;
|
||||
HELPER_EXPECT_SUCCESS(rtsp_manager.initialize());
|
||||
|
||||
// Test that managers can handle rapid successive calls
|
||||
MockAsyncSrsRequest req("/live/lock_test");
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
SrsSharedPtr<SrsRtspSource> rtsp_source;
|
||||
HELPER_EXPECT_SUCCESS(rtsp_manager.fetch_or_create(&req, rtsp_source));
|
||||
EXPECT_TRUE(rtsp_source.get() != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// Test the atomic nature of source creation and pool insertion
|
||||
VOID TEST(SourceLockTest, LiveSourceManager_AtomicSourceCreation2)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
// Test all source manager types
|
||||
SrsRtspSourceManager rtsp_manager;
|
||||
HELPER_EXPECT_SUCCESS(rtsp_manager.initialize());
|
||||
|
||||
MockAsyncSrsRequest req("/live/atomic_test", true); // Enable context switch
|
||||
|
||||
// Test RTSP source manager
|
||||
vector<SrsSharedPtr<SrsRtspSource> > rtsp_sources;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
SrsSharedPtr<SrsRtspSource> source;
|
||||
HELPER_EXPECT_SUCCESS(rtsp_manager.fetch_or_create(&req, source));
|
||||
rtsp_sources.push_back(source);
|
||||
EXPECT_TRUE(source.get() != NULL);
|
||||
if (i > 0) {
|
||||
EXPECT_EQ(rtsp_sources[0].get(), source.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID TEST(SourceLockTest, RtspSourceManager_BasicFunctionality)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
SrsRtspSourceManager manager;
|
||||
HELPER_EXPECT_SUCCESS(manager.initialize());
|
||||
|
||||
MockAsyncSrsRequest req("/live/test3");
|
||||
SrsSharedPtr<SrsRtspSource> source;
|
||||
|
||||
// Test fetch_or_create - should create new source
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source));
|
||||
EXPECT_TRUE(source.get() != NULL);
|
||||
|
||||
// Test fetch - should return the same source
|
||||
SrsSharedPtr<SrsRtspSource> fetched = manager.fetch(&req);
|
||||
EXPECT_TRUE(fetched.get() != NULL);
|
||||
EXPECT_EQ(source.get(), fetched.get());
|
||||
|
||||
// Test fetch_or_create again - should return existing source
|
||||
SrsSharedPtr<SrsRtspSource> source2;
|
||||
HELPER_EXPECT_SUCCESS(manager.fetch_or_create(&req, source2));
|
||||
EXPECT_EQ(source.get(), source2.get());
|
||||
}
|
||||
#endif
|
||||
15
trunk/src/utest/srs_utest_source_lock.hpp
Normal file
15
trunk/src/utest/srs_utest_source_lock.hpp
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
// Copyright (c) 2013-2025 The SRS Authors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
|
||||
#ifndef SRS_UTEST_SOURCE_LOCK_HPP
|
||||
#define SRS_UTEST_SOURCE_LOCK_HPP
|
||||
|
||||
/*
|
||||
#include <srs_utest_source_lock.hpp>
|
||||
*/
|
||||
#include <srs_utest.hpp>
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue
Block a user