文件:
src\app\srs_app_source.hpp
src\app\srs_app_source.cpp
SrsSource代表 living stream source
class SrsSource : public ISrsReloadHandler { private: static std::map<std::string, SrsSource*> pool; public: /** * create source when fetch from cache failed. * @param r the client request. * @param h the event handler for source. * @param pps the matched source, if success never be NULL. */ static int fetch_or_create(SrsRequest* r, ISrsSourceHandler* h, SrsSource** pps); private: /** * get the exists source, NULL when not exists. * update the request and return the exists source. */ static SrsSource* fetch(SrsRequest* r); public: /** * dispose and cycle all sources. */ static void dispose_all(); static int cycle_all(); private: static int do_cycle_all(); public: /** * when system exit, destroy the sources, * for gmc to analysis mem leaks. */ static void destroy(); private: // source id, // for publish, it's the publish client id. // for edge, it's the edge ingest id. // when source id changed, for example, the edge reconnect, // invoke the on_source_id_changed() to let all clients know. int _source_id; // previous source id. int _pre_source_id; // deep copy of client request. SrsRequest* _req; // to delivery stream to clients. std::vector<SrsConsumer*> consumers; // the time jitter algorithm for vhost. SrsRtmpJitterAlgorithm jitter_algorithm; // whether use interlaced/mixed algorithm to correct timestamp. bool mix_correct; SrsMixQueue* mix_queue; // whether stream is monotonically increase. bool is_monotonically_increase; int64_t last_packet_time; // hls handler. #ifdef SRS_AUTO_HLS SrsHls* hls; #endif // dvr handler. #ifdef SRS_AUTO_DVR SrsDvr* dvr; #endif // transcoding handler. #ifdef SRS_AUTO_TRANSCODE SrsEncoder* encoder; #endif #ifdef SRS_AUTO_HDS SrsHds *hds; #endif // edge control service SrsPlayEdge* play_edge; SrsPublishEdge* publish_edge; // gop cache for client fast startup. SrsGopCache* gop_cache; // to forward stream to other servers std::vector<SrsForwarder*> forwarders; // for aggregate message SrsStream* aggregate_stream; // the event handler. ISrsSourceHandler* handler; private: /** * can publish, true when is not streaming */ bool _can_publish; /** * atc whether atc(use absolute time and donot adjust time), * directly use msg time and donot adjust if atc is true, * otherwise, adjust msg time to start from 0 to make flash happy. */ // TODO: FIXME: to support reload atc. bool atc; // last die time, when all consumers quit and no publisher, // we will remove the source when source die. int64_t die_at; private: SrsSharedPtrMessage* cache_metadata; // the cached video sequence header. SrsSharedPtrMessage* cache_sh_video; // the cached audio sequence header. SrsSharedPtrMessage* cache_sh_audio; public: SrsSource(); virtual ~SrsSource(); public: virtual void dispose(); virtual int cycle(); // remove source when expired. virtual bool expired(); // initialize, get and setter. public: /** * initialize the hls with handlers. */ virtual int initialize(SrsRequest* r, ISrsSourceHandler* h); // interface ISrsReloadHandler public: virtual int on_reload_vhost_atc(std::string vhost); virtual int on_reload_vhost_gop_cache(std::string vhost); virtual int on_reload_vhost_queue_length(std::string vhost); virtual int on_reload_vhost_time_jitter(std::string vhost); virtual int on_reload_vhost_mix_correct(std::string vhost); virtual int on_reload_vhost_forward(std::string vhost); virtual int on_reload_vhost_hls(std::string vhost); virtual int on_reload_vhost_hds(std::string vhost); virtual int on_reload_vhost_dvr(std::string vhost); virtual int on_reload_vhost_transcode(std::string vhost); // for the tools callback public: // for the SrsForwarder to callback to request the sequence headers. virtual int on_forwarder_start(SrsForwarder* forwarder); // for the SrsHls to callback to request the sequence headers. virtual int on_hls_start(); // for the SrsDvr to callback to request the sequence headers. virtual int on_dvr_request_sh(); // source id changed. virtual int on_source_id_changed(int id); // get current source id. virtual int source_id(); virtual int pre_source_id(); // logic data methods public: virtual bool can_publish(bool is_edge); virtual int on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata); public: virtual int on_audio(SrsCommonMessage* audio); private: virtual int on_audio_imp(SrsSharedPtrMessage* audio); public: virtual int on_video(SrsCommonMessage* video); private: virtual int on_video_imp(SrsSharedPtrMessage* video); public: virtual int on_aggregate(SrsCommonMessage* msg); /** * publish stream event notify. * @param _req the request from client, the source will deep copy it, * for when reload the request of client maybe invalid. */ virtual int on_publish(); virtual void on_unpublish(); // consumer methods public: /** * create consumer and dumps packets in cache. * @param consumer, output the create consumer. * @param ds, whether dumps the sequence header. * @param dm, whether dumps the metadata. * @param dg, whether dumps the gop cache. */ virtual int create_consumer( SrsConnection* conn, SrsConsumer*& consumer, bool ds = true, bool dm = true, bool dg = true ); virtual void on_consumer_destroy(SrsConsumer* consumer); virtual void set_cache(bool enabled); virtual SrsRtmpJitterAlgorithm jitter(); // internal public: // for edge, when publish edge stream, check the state virtual int on_edge_start_publish(); // for edge, proxy the publish virtual int on_edge_proxy_publish(SrsCommonMessage* msg); // for edge, proxy stop publish virtual void on_edge_proxy_unpublish(); private: virtual int create_forwarders(); virtual void destroy_forwarders(); };
这个类被调用的第一个函数是static member function
fetch_or_create
b SrsSource::fetch_or_create
#0 SrsSource::fetch_or_create (r=0x8f4ff0, h=0x8d5458, pps=0x7ffff7f84a00) at src/app/srs_app_source.cpp:746 #1 0x000000000047f158 in SrsRtmpConn::stream_service_cycle (this=0x8f4ec0) at src/app/srs_app_rtmp_conn.cpp:499 #2 0x000000000047e9d8 in SrsRtmpConn::service_cycle (this=0x8f4ec0) at src/app/srs_app_rtmp_conn.cpp:416 #3 0x000000000047d936 in SrsRtmpConn::do_cycle (this=0x8f4ec0) at src/app/srs_app_rtmp_conn.cpp:211 #4 0x000000000047bc6d in SrsConnection::cycle (this=0x8f4f48) at src/app/srs_app_conn.cpp:89 #5 0x00000000004ad6a3 in SrsOneCycleThread::cycle (this=0x8f4f90) at src/app/srs_app_thread.cpp:372 #6 0x00000000004ace3b in internal::SrsThread::thread_cycle (this=0x8f4fb0) at src/app/srs_app_thread.cpp:207 #7 0x00000000004ad049 in internal::SrsThread::thread_fun (arg=0x8f4fb0) at src/app/srs_app_thread.cpp:245 #8 0x0000000000535371 in _st_thread_main () at sched.c:327 #9 0x0000000000535ae1 in st_thread_create (start=0x7ffff7fdbc20, arg=0x1f7fdbb60, joinable=0, stk_size=5480568) at sched.c:591
int SrsSource::fetch_or_create(SrsRequest* r, ISrsSourceHandler* h, SrsSource** pps) { int ret = ERROR_SUCCESS; SrsSource* source = NULL;
// 根据请求中的app和stream参数在SrsSource pool中寻找已经存在的SrsSource if ((source = fetch(r)) != NULL) { //
*pps = source; return ret; } //在SrsSource 不存在,运行在此处,publish一个没被play的app/stream pair,或play一个没被publish的流 string stream_url = r->get_stream_url(); string vhost = r->vhost; // should always not exists for create a source. srs_assert (pool.find(stream_url) == pool.end()); source = new SrsSource(); if ((ret = source->initialize(r, h)) != ERROR_SUCCESS) { srs_freep(source); return ret; } pool[stream_url] = source; srs_info("create new source for url=%s, vhost=%s", stream_url.c_str(), vhost.c_str()); *pps = source; return ret; } SrsSource* SrsSource::fetch(SrsRequest* r) { SrsSource* source = NULL; // stream_url /hls/stream string stream_url = r->get_stream_url(); if (pool.find(stream_url) == pool.end()) { return NULL; } source = pool[stream_url]; // 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->_req->update_auth(r); return source; }
int SrsSource::initialize(SrsRequest* r, ISrsSourceHandler* h) {
// h参数为SrsRtmpConn类的成员变量server,类型为SrsServer
/*
class SrsServer : virtual public ISrsReloadHandler
, virtual public ISrsSourceHandler
, virtual public IConnectionManager
*/
int ret = ERROR_SUCCESS; srs_assert(h); srs_assert(!_req); handler = h; _req = r->copy();//创建此流的SrsRequest,可能是play或publish
// 通常情况下,服务器分发rtmp stream到client时,时间戳从0开始
// 当 atc打开时,服务器用绝对时间分发rtmp stream 到 client atc = _srs_config->get_atc(_req->vhost); #ifdef SRS_AUTO_HLS if ((ret = hls->initialize(this)) != ERROR_SUCCESS) { return ret; } #endif #ifdef SRS_AUTO_DVR if ((ret = dvr->initialize(this, _req)) != ERROR_SUCCESS) { return ret; } #endif // play edge 里面有一个 ingester,从origin 拉流 if ((ret = play_edge->initialize(this, _req)) != ERROR_SUCCESS) { return ret; }
// publish edge里面有一个 forwarder,转发流到 origin if ((ret = publish_edge->initialize(this, _req)) != ERROR_SUCCESS) { return ret; } double 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); return ret; }
int SrsPublishEdge::initialize(SrsSource* source, SrsRequest* req) { int ret = ERROR_SUCCESS; // forwarder if ((ret = forwarder->initialize(source, this, req)) != ERROR_SUCCESS) { return ret; } return ret; } int SrsPlayEdge::initialize(SrsSource* source, SrsRequest* req) { int ret = ERROR_SUCCESS; // ingester 类型为 SrsEdgeIngester if ((ret = ingester->initialize(source, this, req)) != ERROR_SUCCESS) { return ret; } return ret; }