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

Merge branch v5.0.115 into develop

1. Asan: Support parse asan symbol backtrace log. v5.0.113 (#3324)
2. GB: Refine lazy object GC. v5.0.114 (#3321)
3. Fix #3328: Docker: Avoiding duplicated copy files. v5.0.115
This commit is contained in:
winlin 2022-12-24 10:27:03 +08:00
commit e45563e925
12 changed files with 160 additions and 235 deletions

7
.run/gb28181.run.xml Normal file
View file

@ -0,0 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="gb28181" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="-c conf/gb28181.conf" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" WORKING_DIR="file://$CMakeCurrentBuildDir$/../../../" PASS_PARENT_ENVS_2="true" PROJECT_NAME="srs" TARGET_NAME="srs" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="srs" RUN_TARGET_NAME="srs">
<method v="2">
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
</method>
</configuration>
</component>

View file

@ -23,17 +23,9 @@ WORKDIR /srs/trunk
# Build and install SRS.
# Note that SRT is enabled by default, so we configure without --srt=on.
# Note that we have copied all files by make install.
RUN ./configure --gb28181=on --h265=on --sanitizer-static=on && make && make install
# All config files for SRS.
RUN cp -R conf /usr/local/srs/conf && \
cp research/api-server/static-dir/index.html /usr/local/srs/objs/nginx/html/ && \
cp research/api-server/static-dir/favicon.ico /usr/local/srs/objs/nginx/html/ && \
cp research/players/crossdomain.xml /usr/local/srs/objs/nginx/html/ && \
cp -R research/console /usr/local/srs/objs/nginx/html/ && \
cp -R research/players /usr/local/srs/objs/nginx/html/ && \
cp -R 3rdparty/signaling/www/demos /usr/local/srs/objs/nginx/html/
############################################################
# dist
############################################################

View file

@ -20,6 +20,9 @@ The changelog for SRS.
## SRS 5.0 Changelog
* v5.0, 2022-12-24, Fix [#3328](https://github.com/ossrs/srs/issues/3328): Docker: Avoiding duplicated copy files. v5.0.115
* v5.0, 2022-12-20, Merge [#3321](https://github.com/ossrs/srs/pull/3321): GB: Refine lazy object GC. v5.0.114
* v5.0, 2022-12-18, Merge [#3324](https://github.com/ossrs/srs/pull/3324): Asan: Support parse asan symbol backtrace log. v5.0.113
* v5.0, 2022-12-17, Merge [#3323](https://github.com/ossrs/srs/pull/3323): SRT: Fix srt to rtmp crash when sps or pps empty. v5.0.112
* v5.0, 2022-12-15, For [#3300](https://github.com/ossrs/srs/issues/3300): GB28181: Fix memory overlap for small packets. v5.0.111
* v5.0, 2022-12-14, For [#939](https://github.com/ossrs/srs/issues/939): FLV: Support set default has_av and disable guessing. v5.0.110

View file

@ -139,33 +139,69 @@ extern ISrsLazyGc* _srs_gc;
// A wrapper template for lazy-sweep resource.
// See https://github.com/ossrs/srs/issues/3176#lazy-sweep
//
// Usage for resource which manages itself in coroutine cycle, see SrsLazyGbSession:
// class Resource {
// private:
// SrsLazyObjectWrapper<Resource>* wrapper_;
// private:
// friend class SrsLazyObjectWrapper<Resource>;
// Resource(SrsLazyObjectWrapper<Resource>* wrapper) { wrapper_ = wrapper; }
// public:
// srs_error_t Resource::cycle() {
// srs_error_t err = do_cycle();
// _srs_gb_manager->remove(wrapper_);
// return err;
// }
// };
// SrsLazyObjectWrapper<Resource>* obj = new SrsLazyObjectWrapper<Resource>*();
// _srs_gb_manager->add(obj); // Add wrapper to resource manager.
// Start a coroutine to do obj->resource()->cycle().
//
// Usage for resource managed by other object:
// class Resource {
// private:
// friend class SrsLazyObjectWrapper<Resource>;
// Resource(SrsLazyObjectWrapper<Resource>* /*wrapper*/) {
// }
// };
// class Manager {
// private:
// SrsLazyObjectWrapper<Resource>* wrapper_;
// public:
// Manager() { wrapper_ = new SrsLazyObjectWrapper<Resource>(); }
// ~Manager() { srs_freep(wrapper_); }
// };
// Manager* manager = new Manager();
// srs_freep(manager);
//
// Note that under-layer resource are destroyed by _srs_gc, which is literally equal to srs_freep. However, the root
// wrapper might be managed by other resource manager, such as _srs_gb_manager for SrsLazyGbSession. Furthermore, other
// copied out wrappers might be freed by srs_freep. All are ok, because all wrapper and resources are simply normal
// object, so if you added to manager then you should use manager to remove it, and you can also directly delete it.
template<typename T>
class SrsLazyObjectWrapper : public ISrsResource
{
private:
T* resource_;
bool is_root_;
public:
SrsLazyObjectWrapper(T* resource = NULL, ISrsResource* wrapper = NULL) {
resource_ = resource ? resource : new T();
resource_->gc_use();
is_root_ = !resource;
if (!resource) {
resource_->gc_set_creator_wrapper(wrapper ? wrapper : this);
}
SrsLazyObjectWrapper() {
init(new T(this));
}
virtual ~SrsLazyObjectWrapper() {
resource_->gc_dispose();
if (is_root_) {
resource_->gc_set_creator_wrapper(NULL);
}
if (resource_->gc_ref() == 0) {
_srs_gc->remove(resource_);
}
}
private:
SrsLazyObjectWrapper(T* resource) {
init(resource);
}
void init(T* resource) {
resource_ = resource;
resource_->gc_use();
}
public:
SrsLazyObjectWrapper<T>* copy() {
return new SrsLazyObjectWrapper<T>(resource_);
@ -183,31 +219,6 @@ public:
}
};
// Use macro to generate a wrapper class, because typedef will cause IDE incorrect tips.
// See https://github.com/ossrs/srs/issues/3176#lazy-sweep
#define SRS_LAZY_WRAPPER_GENERATOR(Resource, IWrapper, IResource) \
private: \
SrsLazyObjectWrapper<Resource> impl_; \
public: \
Resource##Wrapper(Resource* resource = NULL) : impl_(resource, this) { \
} \
virtual ~Resource##Wrapper() { \
} \
public: \
IWrapper* copy() { \
return new Resource##Wrapper(impl_.resource()); \
} \
IResource* resource() { \
return impl_.resource(); \
} \
public: \
virtual const SrsContextId& get_id() { \
return impl_.get_id(); \
} \
virtual std::string desc() { \
return impl_.desc(); \
} \
// If a connection is able be expired, user can use HTTP-API to kick-off it.
class ISrsExpire
{

View file

@ -70,42 +70,11 @@ std::string srs_sip_state(SrsGbSipState ostate, SrsGbSipState state)
return srs_fmt("%s->%s", srs_gb_sip_state(ostate).c_str(), srs_gb_sip_state(state).c_str());
}
ISrsGbSipConn::ISrsGbSipConn()
SrsLazyGbSession::SrsLazyGbSession(SrsLazyObjectWrapper<SrsLazyGbSession>* wrapper_root)
{
}
ISrsGbSipConn::~ISrsGbSipConn()
{
}
ISrsGbSipConnWrapper::ISrsGbSipConnWrapper()
{
}
ISrsGbSipConnWrapper::~ISrsGbSipConnWrapper()
{
}
ISrsGbMediaConn::ISrsGbMediaConn()
{
}
ISrsGbMediaConn::~ISrsGbMediaConn()
{
}
ISrsGbMediaConnWrapper::ISrsGbMediaConnWrapper()
{
}
ISrsGbMediaConnWrapper::~ISrsGbMediaConnWrapper()
{
}
SrsLazyGbSession::SrsLazyGbSession()
{
sip_ = new ISrsGbSipConnWrapper();
media_ = new ISrsGbMediaConnWrapper();
wrapper_root_ = wrapper_root;
sip_ = new SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>();
media_ = new SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>();
muxer_ = new SrsGbMuxer(this);
state_ = SrsGbSessionStateInit;
@ -225,7 +194,7 @@ void SrsLazyGbSession::on_ps_pack(SrsPackContext* ctx, SrsPsPacket* ps, const st
}
}
void SrsLazyGbSession::on_sip_transport(ISrsGbSipConnWrapper* sip)
void SrsLazyGbSession::on_sip_transport(SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>* sip)
{
srs_freep(sip_);
sip_ = sip->copy();
@ -234,12 +203,12 @@ void SrsLazyGbSession::on_sip_transport(ISrsGbSipConnWrapper* sip)
sip_->resource()->set_cid(cid_);
}
ISrsGbSipConnWrapper* SrsLazyGbSession::sip_transport()
SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>* SrsLazyGbSession::sip_transport()
{
return sip_;
}
void SrsLazyGbSession::on_media_transport(ISrsGbMediaConnWrapper* media)
void SrsLazyGbSession::on_media_transport(SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>* media)
{
srs_freep(media_);
media_ = media->copy();
@ -273,7 +242,7 @@ srs_error_t SrsLazyGbSession::cycle()
media_->resource()->interrupt();
// Note that we added wrapper to manager, so we must free the wrapper, not this connection.
SrsLazyGbSessionWrapper* wrapper = dynamic_cast<SrsLazyGbSessionWrapper*>(gc_creator_wrapper());
SrsLazyObjectWrapper<SrsLazyGbSession>* wrapper = wrapper_root_;
srs_assert(wrapper); // The creator wrapper MUST never be null, because we created it.
_srs_gb_manager->remove(wrapper);
@ -366,7 +335,7 @@ srs_error_t SrsLazyGbSession::drive_state()
}
// Now, we're able to query session by ssrc, for media packets.
SrsLazyGbSessionWrapper* wrapper = dynamic_cast<SrsLazyGbSessionWrapper*>(gc_creator_wrapper());
SrsLazyObjectWrapper<SrsLazyGbSession>* wrapper = wrapper_root_;
srs_assert(wrapper); // It MUST never be NULL, because this method is in the cycle of coroutine.
_srs_gb_manager->add_with_fast_id(ssrc, wrapper);
}
@ -493,7 +462,7 @@ srs_error_t SrsGbListener::on_tcp_client(ISrsListener* listener, srs_netfd_t stf
// Handle TCP connections.
if (listener == sip_listener_) {
SrsLazyGbSipTcpConnWrapper* conn = new SrsLazyGbSipTcpConnWrapper();
SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>* conn = new SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>();
SrsLazyGbSipTcpConn* resource = dynamic_cast<SrsLazyGbSipTcpConn*>(conn->resource());
resource->setup(conf_, sip_listener_, media_listener_, stfd);
@ -504,7 +473,7 @@ srs_error_t SrsGbListener::on_tcp_client(ISrsListener* listener, srs_netfd_t stf
_srs_gb_manager->add(conn, NULL);
} else if (listener == media_listener_) {
SrsLazyGbMediaTcpConnWrapper* conn = new SrsLazyGbMediaTcpConnWrapper();
SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>* conn = new SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>();
SrsLazyGbMediaTcpConn* resource = dynamic_cast<SrsLazyGbMediaTcpConn*>(conn->resource());
resource->setup(stfd);
@ -522,8 +491,9 @@ srs_error_t SrsGbListener::on_tcp_client(ISrsListener* listener, srs_netfd_t stf
return err;
}
SrsLazyGbSipTcpConn::SrsLazyGbSipTcpConn()
SrsLazyGbSipTcpConn::SrsLazyGbSipTcpConn(SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>* wrapper_root)
{
wrapper_root_ = wrapper_root;
session_ = NULL;
state_ = SrsGbSipStateInit;
register_ = new SrsSipMessage();
@ -940,7 +910,7 @@ srs_error_t SrsLazyGbSipTcpConn::cycle()
sender_->interrupt();
// Note that we added wrapper to manager, so we must free the wrapper, not this connection.
SrsLazyGbSipTcpConnWrapper* wrapper = dynamic_cast<SrsLazyGbSipTcpConnWrapper*>(gc_creator_wrapper());
SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>* wrapper = wrapper_root_;
srs_assert(wrapper); // The creator wrapper MUST never be null, because we created it.
_srs_gb_manager->remove(wrapper);
@ -987,7 +957,7 @@ srs_error_t SrsLazyGbSipTcpConn::do_cycle()
return err;
}
srs_error_t SrsLazyGbSipTcpConn::bind_session(SrsSipMessage* msg, SrsLazyGbSessionWrapper** psession)
srs_error_t SrsLazyGbSipTcpConn::bind_session(SrsSipMessage* msg, SrsLazyObjectWrapper<SrsLazyGbSession>** psession)
{
srs_error_t err = srs_success;
@ -998,14 +968,14 @@ srs_error_t SrsLazyGbSipTcpConn::bind_session(SrsSipMessage* msg, SrsLazyGbSessi
if (msg->type_ != HTTP_REQUEST || msg->method_ != HTTP_REGISTER) return err;
// The lazy-sweep wrapper for this resource.
SrsLazyGbSipTcpConnWrapper* wrapper = dynamic_cast<SrsLazyGbSipTcpConnWrapper*>(gc_creator_wrapper());
SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>* wrapper = wrapper_root_;
srs_assert(wrapper); // It MUST never be NULL, because this method is in the cycle of coroutine of receiver.
// Find exists session for register, might be created by another object and still alive.
SrsLazyGbSessionWrapper* session = dynamic_cast<SrsLazyGbSessionWrapper*>(_srs_gb_manager->find_by_id(device));
SrsLazyObjectWrapper<SrsLazyGbSession>* session = dynamic_cast<SrsLazyObjectWrapper<SrsLazyGbSession>*>(_srs_gb_manager->find_by_id(device));
if (!session) {
// Create new GB session.
session = new SrsLazyGbSessionWrapper();
session = new SrsLazyObjectWrapper<SrsLazyGbSession>();
if ((err = session->resource()->initialize(conf_)) != srs_success) {
srs_freep(session);
@ -1248,8 +1218,9 @@ ISrsPsPackHandler::~ISrsPsPackHandler()
{
}
SrsLazyGbMediaTcpConn::SrsLazyGbMediaTcpConn()
SrsLazyGbMediaTcpConn::SrsLazyGbMediaTcpConn(SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>* wrapper_root)
{
wrapper_root_ = wrapper_root;
pack_ = new SrsPackContext(this);
trd_ = new SrsSTCoroutine("media", this);
buffer_ = new uint8_t[65535];
@ -1324,7 +1295,7 @@ srs_error_t SrsLazyGbMediaTcpConn::cycle()
srs_trace("PS: Media disconnect, code=%d", srs_error_code(err));
// Note that we added wrapper to manager, so we must free the wrapper, not this connection.
SrsLazyGbMediaTcpConnWrapper* wrapper = dynamic_cast<SrsLazyGbMediaTcpConnWrapper*>(gc_creator_wrapper());
SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>* wrapper = wrapper_root_;
srs_assert(wrapper); // The creator wrapper MUST never be null, because we created it.
_srs_gb_manager->remove(wrapper);
@ -1478,18 +1449,18 @@ srs_error_t SrsLazyGbMediaTcpConn::on_ps_pack(SrsPsPacket* ps, const std::vector
return err;
}
srs_error_t SrsLazyGbMediaTcpConn::bind_session(uint32_t ssrc, SrsLazyGbSessionWrapper** psession)
srs_error_t SrsLazyGbMediaTcpConn::bind_session(uint32_t ssrc, SrsLazyObjectWrapper<SrsLazyGbSession>** psession)
{
srs_error_t err = srs_success;
if (!ssrc) return err;
// The lazy-sweep wrapper for this resource.
SrsLazyGbMediaTcpConnWrapper* wrapper = dynamic_cast<SrsLazyGbMediaTcpConnWrapper*>(gc_creator_wrapper());
SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>* wrapper = wrapper_root_;
srs_assert(wrapper); // It MUST never be NULL, because this method is in the cycle of coroutine.
// Find exists session for register, might be created by another object and still alive.
SrsLazyGbSessionWrapper* session = dynamic_cast<SrsLazyGbSessionWrapper*>(_srs_gb_manager->find_by_fast_id(ssrc));
SrsLazyObjectWrapper<SrsLazyGbSession>* session = dynamic_cast<SrsLazyObjectWrapper<SrsLazyGbSession>*>(_srs_gb_manager->find_by_fast_id(ssrc));
if (!session) return err;
_srs_gb_manager->add_with_fast_id(ssrc, session);

View file

@ -29,8 +29,6 @@ class SrsSipMessage;
class SrsLazyGbSession;
class SrsLazyGbSipTcpConn;
class SrsLazyGbMediaTcpConn;
class SrsLazyGbSipTcpConnWrapper;
class SrsLazyGbMediaTcpConnWrapper;
class SrsLazyGbSipTcpReceiver;
class SrsLazyGbSipTcpSender;
class SrsAlonePithyPrint;
@ -88,76 +86,6 @@ enum SrsGbSipState
};
std::string srs_gb_sip_state(SrsGbSipState state);
// The interface for GB SIP or HTTP-API connection.
class ISrsGbSipConn
{
public:
ISrsGbSipConn();
virtual ~ISrsGbSipConn();
public:
// Interrupt the transport, because session is disposing.
virtual void interrupt() {}
// Get the device id of device, also used as RTMP stream name.
virtual std::string device_id() { return "livestream"; }
// Get the state of SIP.
virtual SrsGbSipState state() { return SrsGbSipStateInit; }
// Reset the SIP state to registered, for re-inviting.
virtual void reset_to_register() {}
// Whether device is already registered, which might drive the session to connecting state.
virtual bool is_registered() { return false; }
// Whether device is stable state, which means it's sending heartbeat message.
virtual bool is_stable() { return false; }
// Whether device is request to bye, which means there might be no stream ever and so the session should be
// disposed. This is the control event from client device.
virtual bool is_bye() { return false; }
// Send invite to device, for SIP it should be an "INVITE" request message. Output the ssrc as ID of session, for
// media connection to load from SSRC while receiving and handling RTP packets.
virtual srs_error_t invite_request(uint32_t* pssrc) { return srs_success; }
// Change id of coroutine.
virtual void set_cid(const SrsContextId& cid) {}
};
// The wrapper for ISrsGbSipConn.
class ISrsGbSipConnWrapper
{
private:
ISrsGbSipConn dummy_;
public:
ISrsGbSipConnWrapper();
virtual ~ISrsGbSipConnWrapper();
public:
virtual ISrsGbSipConn* resource() { return &dummy_; }
virtual ISrsGbSipConnWrapper* copy() { return new ISrsGbSipConnWrapper(); }
};
// The interface for GB media over TCP or UDP transport.
class ISrsGbMediaConn
{
public:
ISrsGbMediaConn();
virtual ~ISrsGbMediaConn();
public:
// Interrupt the transport, because session is disposing.
virtual void interrupt() {}
// Whether media transport is connected. SRS will invite client to publish stream if not connected.
virtual bool is_connected() { return false; }
// Change id of coroutine.
virtual void set_cid(const SrsContextId& cid) {}
};
// The wrapper for ISrsGbMediaConn.
class ISrsGbMediaConnWrapper
{
private:
ISrsGbMediaConn dummy_;
public:
ISrsGbMediaConnWrapper();
virtual ~ISrsGbMediaConnWrapper();
public:
virtual ISrsGbMediaConn* resource() { return &dummy_; }
virtual ISrsGbMediaConnWrapper* copy() { return new ISrsGbMediaConnWrapper(); }
};
// The main logic object for GB, the session.
class SrsLazyGbSession : public SrsLazyObject, public ISrsResource, public ISrsStartable, public ISrsCoroutineHandler
{
@ -166,8 +94,9 @@ private:
SrsContextId cid_;
private:
SrsGbSessionState state_;
ISrsGbSipConnWrapper* sip_;
ISrsGbMediaConnWrapper* media_;
SrsLazyObjectWrapper<SrsLazyGbSession>* wrapper_root_;
SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>* sip_;
SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>* media_;
SrsGbMuxer* muxer_;
private:
// The candidate for SDP in configuration.
@ -202,7 +131,7 @@ private:
uint64_t media_reserved_;
private:
friend class SrsLazyObjectWrapper<SrsLazyGbSession>;
SrsLazyGbSession();
SrsLazyGbSession(SrsLazyObjectWrapper<SrsLazyGbSession>* wrapper_root);
public:
virtual ~SrsLazyGbSession();
public:
@ -211,10 +140,10 @@ public:
// When got a pack of messages.
void on_ps_pack(SrsPackContext* ctx, SrsPsPacket* ps, const std::vector<SrsTsMessage*>& msgs);
// When got available SIP transport.
void on_sip_transport(ISrsGbSipConnWrapper* sip);
ISrsGbSipConnWrapper* sip_transport();
void on_sip_transport(SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>* sip);
SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>* sip_transport();
// When got available media transport.
void on_media_transport(ISrsGbMediaConnWrapper* media);
void on_media_transport(SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>* media);
// Get the candidate for SDP generation, the public IP address for device to connect to.
std::string pip();
// Interface ISrsStartable
@ -234,12 +163,6 @@ public:
virtual std::string desc();
};
// Lazy-sweep wrapper for GB session.
class SrsLazyGbSessionWrapper : public ISrsResource
{
SRS_LAZY_WRAPPER_GENERATOR(SrsLazyGbSession, SrsLazyGbSessionWrapper, SrsLazyGbSession);
};
// The SIP and Media listener for GB.
class SrsGbListener : public ISrsListener, public ISrsTcpHandler
{
@ -261,11 +184,11 @@ public:
// A GB28181 TCP SIP connection.
class SrsLazyGbSipTcpConn : public SrsLazyObject, public ISrsResource, public ISrsStartable, public ISrsCoroutineHandler
, public ISrsGbSipConn
{
private:
SrsGbSipState state_;
SrsLazyGbSessionWrapper* session_;
SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>* wrapper_root_;
SrsLazyObjectWrapper<SrsLazyGbSession>* session_;
SrsSipMessage* register_;
SrsSipMessage* invite_ok_;
private:
@ -282,7 +205,7 @@ private:
SrsCoroutine* trd_;
private:
friend class SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>;
SrsLazyGbSipTcpConn();
SrsLazyGbSipTcpConn(SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>* wrapper_root);
public:
virtual ~SrsLazyGbSipTcpConn();
public:
@ -337,13 +260,7 @@ private:
virtual srs_error_t do_cycle();
private:
// Create session if no one, or bind to an existed session.
srs_error_t bind_session(SrsSipMessage* msg, SrsLazyGbSessionWrapper** psession);
};
// Lazy-sweep wrapper for GB SIP TCP connection.
class SrsLazyGbSipTcpConnWrapper : public ISrsResource, public ISrsGbSipConnWrapper
{
SRS_LAZY_WRAPPER_GENERATOR(SrsLazyGbSipTcpConn, ISrsGbSipConnWrapper, ISrsGbSipConn);
srs_error_t bind_session(SrsSipMessage* msg, SrsLazyObjectWrapper<SrsLazyGbSession>** psession);
};
// Start a coroutine to receive SIP messages.
@ -414,11 +331,12 @@ public:
// A GB28181 TCP media connection, for PS stream.
class SrsLazyGbMediaTcpConn : public SrsLazyObject, public ISrsResource, public ISrsStartable, public ISrsCoroutineHandler
, public ISrsPsPackHandler, public ISrsGbMediaConn
, public ISrsPsPackHandler
{
private:
bool connected_;
SrsLazyGbSessionWrapper* session_;
SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>* wrapper_root_;
SrsLazyObjectWrapper<SrsLazyGbSession>* session_;
uint32_t nn_rtcp_;
private:
SrsPackContext* pack_;
@ -427,7 +345,7 @@ private:
uint8_t* buffer_;
private:
friend class SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>;
SrsLazyGbMediaTcpConn();
SrsLazyGbMediaTcpConn(SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>* wrapper_root);
public:
virtual ~SrsLazyGbMediaTcpConn();
public:
@ -456,13 +374,7 @@ public:
virtual srs_error_t on_ps_pack(SrsPsPacket* ps, const std::vector<SrsTsMessage*>& msgs);
private:
// Create session if no one, or bind to an existed session.
srs_error_t bind_session(uint32_t ssrc, SrsLazyGbSessionWrapper** psession);
};
// Lazy-sweep wrapper for GB Media TCP connection.
class SrsLazyGbMediaTcpConnWrapper : public ISrsResource, public ISrsGbMediaConnWrapper
{
SRS_LAZY_WRAPPER_GENERATOR(SrsLazyGbMediaTcpConn, ISrsGbMediaConnWrapper, ISrsGbMediaConn);
srs_error_t bind_session(uint32_t ssrc, SrsLazyObjectWrapper<SrsLazyGbSession>** psession);
};
// The queue for mpegts over udp to send packets.

View file

@ -9,6 +9,6 @@
#define VERSION_MAJOR 5
#define VERSION_MINOR 0
#define VERSION_REVISION 112
#define VERSION_REVISION 115
#endif

View file

@ -7,6 +7,7 @@
#include <srs_kernel_error.hpp>
#include <srs_kernel_log.hpp>
#include <srs_kernel_utility.hpp>
#include <errno.h>
#include <sstream>
@ -15,6 +16,7 @@
#include <assert.h>
#include <map>
#include <vector>
using namespace std;
#if defined(SRS_BACKTRACE) && defined(__linux)
@ -118,6 +120,53 @@ char* addr2line_format(void* addr, char* symbol, char* buffer, int nn_buffer)
}
#endif
int srs_parse_asan_backtrace_symbols(char* symbol, char* out_buf)
{
#if defined(SRS_BACKTRACE) && defined(__linux)
void* frame = parse_symbol_offset(symbol);
if (!frame) {
return ERROR_BACKTRACE_PARSE_OFFSET;
}
char* fmt = addr2line_format(frame, symbol, out_buf, sizeof(out_buf));
if (fmt != out_buf) {
return ERROR_BACKTRACE_ADDR2LINE;
}
return ERROR_SUCCESS;
#endif
return ERROR_BACKTRACE_PARSE_NOT_SUPPORT;
}
#ifdef SRS_SANITIZER_LOG
void asan_report_callback(const char* str)
{
static char buf[256];
// No error code for assert failed.
errno = 0;
std::vector<std::string> asan_logs = srs_string_split(string(str), "\n");
size_t log_count = asan_logs.size();
for (size_t i = 0; i < log_count; i++) {
std::string log = asan_logs[i];
if (!srs_string_starts_with(srs_string_trim_start(log, " "), "#")) {
srs_error("%s", log.c_str());
continue;
}
buf[0] = 0;
int r0 = srs_parse_asan_backtrace_symbols((char*)log.c_str(), buf);
if (r0 != ERROR_SUCCESS) {
srs_error("%s, r0=%d", log.c_str(), r0);
} else {
srs_error("%s, %s", log.c_str(), buf);
}
}
}
#endif
bool srs_is_system_control_error(srs_error_t err)
{
int error_code = srs_error_code(err);

View file

@ -102,6 +102,9 @@
XX(ERROR_APM_AUTH , 1089, "ApmAuth", "APM team or token is invalid") \
XX(ERROR_EXPORTER_DISABLED , 1090, "ExporterDisable", "Prometheus exporter is disabled") \
XX(ERROR_ST_SET_SELECT , 1091, "StSetSelect", "ST set select failed") \
XX(ERROR_BACKTRACE_PARSE_NOT_SUPPORT , 1092, "BacktraceParseNotSupport", "Backtrace parse not supported") \
XX(ERROR_BACKTRACE_PARSE_OFFSET , 1093, "BacktraceParseOffset", "Parse backtrace offset failed") \
XX(ERROR_BACKTRACE_ADDR2LINE , 1094, "BacktraceAddr2Line", "Backtrace addr2line failed") \
/**************************************************/
/* RTMP protocol error. */

View file

@ -42,6 +42,7 @@ using namespace std;
#include <srs_kernel_file.hpp>
#include <srs_app_hybrid.hpp>
#include <srs_app_threads.hpp>
#include <srs_kernel_error.hpp>
#ifdef SRS_RTC
#include <srs_app_rtc_conn.hpp>
@ -82,10 +83,7 @@ const char* _srs_binary = NULL;
extern void srs_free_global_system_ips();
#ifdef SRS_SANITIZER_LOG
void asan_report_callback(const char* str)
{
srs_trace("%s", str);
}
extern void asan_report_callback(const char* str);
#endif
/**

View file

@ -43,23 +43,20 @@ ISrsConnection::~ISrsConnection()
SrsLazyObject::SrsLazyObject()
{
gc_ref_ = 0;
gc_creator_wrapper_ = NULL;
}
SrsLazyObject::~SrsLazyObject()
{
}
SrsLazyObject* SrsLazyObject::gc_use()
void SrsLazyObject::gc_use()
{
gc_ref_++;
return this;
}
SrsLazyObject* SrsLazyObject::gc_dispose()
void SrsLazyObject::gc_dispose()
{
gc_ref_--;
return this;
}
int32_t SrsLazyObject::gc_ref()
@ -67,16 +64,6 @@ int32_t SrsLazyObject::gc_ref()
return gc_ref_;
}
void SrsLazyObject::gc_set_creator_wrapper(ISrsResource* wrapper)
{
gc_creator_wrapper_ = wrapper;
}
ISrsResource* SrsLazyObject::gc_creator_wrapper()
{
return gc_creator_wrapper_;
}
ISrsLazyGc::ISrsLazyGc()
{
}

View file

@ -55,24 +55,16 @@ class SrsLazyObject
private:
// The reference count of resource, 0 is no wrapper and safe to sweep.
int32_t gc_ref_;
// The creator wrapper, which created this resource. Note that it might be disposed and the pointer is NULL, so be
// careful and make sure to check it before use it.
ISrsResource* gc_creator_wrapper_;
public:
SrsLazyObject();
virtual ~SrsLazyObject();
public:
// For wrapper to use this resource.
virtual SrsLazyObject* gc_use();
virtual void gc_use();
// For wrapper to dispose this resource.
virtual SrsLazyObject* gc_dispose();
virtual void gc_dispose();
// The current reference count of resource.
virtual int32_t gc_ref();
public:
// Set the creator wrapper, from which resource clone wrapper.
virtual void gc_set_creator_wrapper(ISrsResource* wrapper);
// Get the first available wrapper. NULL if the creator wrapper disposed.
virtual ISrsResource* gc_creator_wrapper();
};
// The lazy-sweep GC, wait for a long time to dispose resource even when resource is disposable.