mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	GB: Refine lazy object GC. v5.0.114 (#3321)
* GB: Refine lazy object GC. 1. Remove gc_set_creator_wrapper, pass by resource constructor. 2. Remove SRS_LAZY_WRAPPER_GENERATOR macro, use template directly. 3. Remove interfaces ISrsGbSipConn and ISrsGbSipConnWrapper. 4. Remove ISrsGbMediaConn and ISrsGbMediaConnWrapper. * GC: Refine wrapper constructor. * GB: Refine lazy object GC. v5.0.114
This commit is contained in:
		
							parent
							
								
									7eaee46f1f
								
							
						
					
					
						commit
						6f3d6b9b65
					
				
					 8 changed files with 104 additions and 223 deletions
				
			
		|  | @ -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 | ||||
| { | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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.
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue