1. 类定义

1.1 SrsConfig 类

/**
* the config service provider.
* for the config supports reload, so never keep the reference cross st-thread,
* that is, never save the SrsConfDirective* get by any api of config,
* for it maybe free in the reload st-thread cycle.
* you can keep it before st-thread switch, or simply never keep it.
*/
class SrsConfig
{
// user command
private:/*** whether srs is run in dolphin mode.* @see https://github.com/ossrs/srs-dolphin*/bool dolphin;std::string dolphin_rtmp_port;std::string dolphin_http_port;/*** whether show help and exit.*/bool show_help;/*** whether test config file and exit.*/bool test_conf;/*** whether show SRS version and exit.*/bool show_version;
// global env variables.
private:/*** the user parameters, the argc and argv.* the argv is " ".join(argv), where argv is from main(argc, argv).*/std::string _argv;/*** current working directory.*/std::string _cwd;
// config section
private:/*** the last parsed config file.* if reload, reload the config file.*/std::string config_file;/*** the directive root.*/SrsConfDirective* root;
// reload section
private:/*** the reload subscribers, when reload, callback all handlers.*/std::vector<ISrsReloadHandler*> subscribes;
public:SrsConfig();virtual ~SrsConfig();
// dolphin
public:/*** whether srs is in dolphin mode.*/virtual bool is_dolphin();
private:virtual void set_config_directive(SrsConfDirective* parent, std::string dir, std::string value);
// reload
public:/*** for reload handler to register itself,* when config service do the reload, callback the handler.*/virtual void subscribe(ISrsReloadHandler* handler);/*** for reload handler to unregister itself.*/virtual void unsubscribe(ISrsReloadHandler* handler);/*** reload the config file.* @remark, user can test the config before reload it.*/virtual int reload();
private:/*** reload the vhost section of config.*/virtual int reload_vhost(SrsConfDirective* old_root);
protected:/*** reload from the config.* @remark, use protected for the utest to override with mock.*/virtual int reload_conf(SrsConfig* conf);
private:/*** reload the http_api section of config.*/virtual int reload_http_api(SrsConfDirective* old_root);/*** reload the http_stream section of config.*/virtual int reload_http_stream(SrsConfDirective* old_root);/*** reload the transcode section of vhost of config.*/virtual int reload_transcode(SrsConfDirective* new_vhost, SrsConfDirective* old_vhost);/*** reload the ingest section of vhost of config.*/virtual int reload_ingest(SrsConfDirective* new_vhost, SrsConfDirective* old_vhost);
// parse options and file
public:/*** parse the cli, the main(argc,argv) function.*/virtual int parse_options(int argc, char** argv);/*** initialize the cwd for server,* because we may change the workdir.*/virtual int initialize_cwd();/*** get the config file path.*/virtual std::string config();
private:/*** parse each argv.*/virtual int parse_argv(int& i, char** argv);/*** print help and exit.*/virtual void print_help(char** argv);
public:/*** parse the config file, which is specified by cli.*/virtual int parse_file(const char* filename);/*** check the parsed config.*/virtual int check_config();
protected:/*** parse config from the buffer.* @param buffer, the config buffer, user must delete it.* @remark, use protected for the utest to override with mock.*/virtual int parse_buffer(_srs_internal::SrsConfigBuffer* buffer);
// global env
public:/*** get the current work directory.*/virtual std::string         cwd();/*** get the cli, the main(argc,argv), program start command.*/virtual std::string         argv();
// global section
public:/*** get the directive root, corresponding to the config file.* the root directive, no name and args, contains directives.* all directive parsed can retrieve from root.*/virtual SrsConfDirective*   get_root();/*** get the deamon config.* if true, SRS will run in deamon mode, fork and fork to reap the * grand-child process to init process.*/virtual bool                get_deamon();/*** get the max connections limit of system.* if exceed the max connection, SRS will disconnect the connection.* @remark, linux will limit the connections of each process, *       for example, when you need SRS to service 10000+ connections,*       user must use "ulimit -HSn 10000" and config the max connections*       of SRS.*/virtual int                 get_max_connections();/*** get the listen port of SRS.* user can specifies multiple listen ports,* each args of directive is a listen port.*/virtual std::vector<std::string>        get_listens();/*** get the pid file path.* the pid file is used to save the pid of SRS,* use file lock to prevent multiple SRS starting.* @remark, if user need to run multiple SRS instance,*       for example, to start multiple SRS for multiple CPUs,*       user can use different pid file for each process.*/virtual std::string         get_pid_file();/*** get pithy print pulse ms,* for example, all rtmp connections only print one message* every this interval in ms.*/virtual int                 get_pithy_print_ms();/*** whether use utc-time to format the time.*/virtual bool                get_utc_time();/*** get the configed work dir.* ignore if empty string.*/virtual std::string         get_work_dir();// whether use asprocess mode.virtual bool                get_asprocess();
// stream_caster section
public:/*** get all stream_caster in config file.*/virtual std::vector<SrsConfDirective*>  get_stream_casters();/*** get whether the specified stream_caster is enabled.*/virtual bool                get_stream_caster_enabled(SrsConfDirective* sc);/*** get the engine of stream_caster, the caster config.*/virtual std::string         get_stream_caster_engine(SrsConfDirective* sc);/*** get the output rtmp url of stream_caster, the output config.*/virtual std::string         get_stream_caster_output(SrsConfDirective* sc);/*** get the listen port of stream caster.*/virtual int                 get_stream_caster_listen(SrsConfDirective* sc);/*** get the min udp port for rtp of stream caster rtsp.*/virtual int                 get_stream_caster_rtp_port_min(SrsConfDirective* sc);/*** get the max udp port for rtp of stream caster rtsp.*/virtual int                 get_stream_caster_rtp_port_max(SrsConfDirective* sc);
// vhost specified section
public:/*** get the vhost directive by vhost name.* @param vhost, the name of vhost to get.*/virtual SrsConfDirective*   get_vhost(std::string vhost);/*** get all vhosts in config file.*/virtual void get_vhosts(std::vector<SrsConfDirective*>& vhosts);/*** whether vhost is enabled* @param vhost, the vhost name.* @return true when vhost is ok; otherwise, false.*/virtual bool                get_vhost_enabled(std::string vhost);/*** whether vhost is enabled* @param vhost, the vhost directive.* @return true when vhost is ok; otherwise, false.*/virtual bool                get_vhost_enabled(SrsConfDirective* vhost);/*** whether gop_cache is enabled of vhost.* gop_cache used to cache last gop, for client to fast startup.* @return true when gop_cache is ok; otherwise, false.* @remark, default true.*/virtual bool                get_gop_cache(std::string vhost);/*** whether debug_srs_upnode is enabled of vhost.* debug_srs_upnode is very important feature for tracable log,* but some server, for instance, flussonic donot support it.* @see https://github.com/ossrs/srs/issues/160* @return true when debug_srs_upnode is ok; otherwise, false.* @remark, default true.*/virtual bool                get_debug_srs_upnode(std::string vhost);/*** whether atc is enabled of vhost.* atc always use encoder timestamp, SRS never adjust the time.* @return true when atc is ok; otherwise, false.* @remark, default false.*/virtual bool                get_atc(std::string vhost);/*** whether atc_auto is enabled of vhost.* atc_auto used to auto enable atc, when metadata specified the bravo_atc.* @return true when atc_auto is ok; otherwise, false.* @remark, default true.*/virtual bool                get_atc_auto(std::string vhost);/*** get the time_jitter algorithm.* @return the time_jitter algorithm, defined in SrsRtmpJitterAlgorithm.* @remark, default full.*/virtual int                 get_time_jitter(std::string vhost);/*** whether use mix correct algorithm to ensure the timestamp* monotonically increase.*/virtual bool                get_mix_correct(std::string vhost);/*** get the cache queue length, in seconds.* when exceed the queue length, drop packet util I frame.* @remark, default 10.*/virtual double              get_queue_length(std::string vhost);/*** get the refer antisuck directive.* each args of directive is a refer config.* when the client refer(pageUrl) not match the refer config,* SRS will reject the connection.* @remark, default NULL.*/virtual SrsConfDirective*   get_refer(std::string vhost);/*** get the play refer, refer for play clients.* @remark, default NULL.*/virtual SrsConfDirective*   get_refer_play(std::string vhost);/*** get the publish refer, refer for publish clients.* @remark, default NULL.*/virtual SrsConfDirective*   get_refer_publish(std::string vhost);/*** get the chunk size of vhost.* @param vhost, the vhost to get the chunk size. use global if not specified.*       empty string to get the global.* @remark, default 60000.*/virtual int                 get_chunk_size(std::string vhost);/*** whether parse the sps when publish stream to SRS.*/virtual bool                get_parse_sps(std::string vhost);/*** whether mr is enabled for vhost.* @param vhost, the vhost to get the mr.*/virtual bool                get_mr_enabled(std::string vhost);/*** get the mr sleep time in ms for vhost.* @param vhost, the vhost to get the mr sleep time.*/// TODO: FIXME: add utest for mr config.virtual int                 get_mr_sleep_ms(std::string vhost);/*** get the mw sleep time in ms for vhost.* @param vhost, the vhost to get the mw sleep time.*/// TODO: FIXME: add utest for mw config.virtual int                 get_mw_sleep_ms(std::string vhost);/*** whether min latency mode enabled.* @param vhost, the vhost to get the min_latency.*/// TODO: FIXME: add utest for min_latency.virtual bool                get_realtime_enabled(std::string vhost);/*** whether enable tcp nodelay for all clients of vhost.*/virtual bool                get_tcp_nodelay(std::string vhost);/*** the minimal send interval in ms.*/virtual double              get_send_min_interval(std::string vhost);/*** whether reduce the sequence header.*/virtual bool                get_reduce_sequence_header(std::string vhost);/*** the 1st packet timeout in ms for encoder.*/virtual int                 get_publish_1stpkt_timeout(std::string vhost);/*** the normal packet timeout in ms for encoder.*/virtual int                 get_publish_normal_timeout(std::string vhost);
private:/*** get the global chunk size.*/virtual int                 get_global_chunk_size();
// forward section
public:/*** get the forward directive of vhost.*/virtual SrsConfDirective*   get_forward(std::string vhost);
// http_hooks section
private:/*** get the http_hooks directive of vhost.*/virtual SrsConfDirective*   get_vhost_http_hooks(std::string vhost);
public:/*** whether vhost http-hooks enabled.* @remark, if not enabled, donot callback all http hooks.*/virtual bool                get_vhost_http_hooks_enabled(std::string vhost);/*** get the on_connect callbacks of vhost.* @return the on_connect callback directive, the args is the url to callback.*/virtual SrsConfDirective*   get_vhost_on_connect(std::string vhost);/*** get the on_close callbacks of vhost.* @return the on_close callback directive, the args is the url to callback.*/virtual SrsConfDirective*   get_vhost_on_close(std::string vhost);/*** get the on_publish callbacks of vhost.* @return the on_publish callback directive, the args is the url to callback.*/virtual SrsConfDirective*   get_vhost_on_publish(std::string vhost);/*** get the on_unpublish callbacks of vhost.* @return the on_unpublish callback directive, the args is the url to callback.*/virtual SrsConfDirective*   get_vhost_on_unpublish(std::string vhost);/*** get the on_play callbacks of vhost.* @return the on_play callback directive, the args is the url to callback.*/virtual SrsConfDirective*   get_vhost_on_play(std::string vhost);/*** get the on_stop callbacks of vhost.* @return the on_stop callback directive, the args is the url to callback.*/virtual SrsConfDirective*   get_vhost_on_stop(std::string vhost);/*** get the on_dvr callbacks of vhost.* @return the on_dvr callback directive, the args is the url to callback.*/virtual SrsConfDirective*   get_vhost_on_dvr(std::string vhost);/*** get the on_hls callbacks of vhost.* @return the on_hls callback directive, the args is the url to callback.*/virtual SrsConfDirective*   get_vhost_on_hls(std::string vhost);/*** get the on_hls_notify callbacks of vhost.* @return the on_hls_notify callback directive, the args is the url to callback.*/virtual SrsConfDirective*   get_vhost_on_hls_notify(std::string vhost);
// bwct(bandwidth check tool) section
public:/*** whether bw check enabled for vhost.* if enabled, serve all clients with bandwidth check services.* oterwise, serve all cleints with stream.*/virtual bool                get_bw_check_enabled(std::string vhost);/*** the key of server, if client key mot match, reject.*/virtual std::string         get_bw_check_key(std::string vhost);/*** the check interval, in ms.* if the client request check in very short time(in the interval),* SRS will reject client.* @remark this is used to prevent the bandwidth check attack.*/virtual int                 get_bw_check_interval_ms(std::string vhost);/*** the max kbps that user can test,* if exceed the kbps, server will slowdown the send-recv.* @remark this is used to protect the service bandwidth.*/virtual int                 get_bw_check_limit_kbps(std::string vhost);
// vhost edge section
public:/*** whether vhost is edge mode.* for edge, publish client will be proxyed to upnode,* for edge, play client will share a connection to get stream from upnode.*/virtual bool                get_vhost_is_edge(std::string vhost);/*** whether vhost is edge mode.* for edge, publish client will be proxyed to upnode,* for edge, play client will share a connection to get stream from upnode.*/virtual bool                get_vhost_is_edge(SrsConfDirective* vhost);/*** get the origin config of edge,* specifies the origin ip address, port.*/virtual SrsConfDirective*   get_vhost_edge_origin(std::string vhost);/*** whether edge token tranverse is enabled,* if true, edge will send connect origin to verfy the token of client.* for example, we verify all clients on the origin FMS by server-side as,* all clients connected to edge must be tranverse to origin to verify.*/virtual bool                get_vhost_edge_token_traverse(std::string vhost);/*** get the transformed vhost for edge,* @see https://github.com/ossrs/srs/issues/372*/virtual std::string         get_vhost_edge_transform_vhost(std::string vhost);
// vhost security section
public:/*** whether the secrity of vhost enabled.*/virtual bool                get_security_enabled(std::string vhost);/*** get the security rules.*/virtual SrsConfDirective*   get_security_rules(std::string vhost);
// vhost transcode section
public:/*** get the transcode directive of vhost in specified scope.* @param vhost, the vhost name to get the transcode directive.* @param scope, the scope, empty to get all. for example, user can transcode*       the app scope stream, by config with app:*                   transcode live {...}*       when the scope is "live", this directive is matched.*       the scope can be: empty for all, app, app/stream.* @remark, please see the samples of full.conf, the app.transcode.srs.com*       and stream.transcode.srs.com.*/virtual SrsConfDirective*   get_transcode(std::string vhost, std::string scope);/*** whether the transcode directive is enabled.*/virtual bool                get_transcode_enabled(SrsConfDirective* transcode);/*** get the ffmpeg tool path of transcode.*/virtual std::string         get_transcode_ffmpeg(SrsConfDirective* transcode);/*** get the engines of transcode.*/virtual std::vector<SrsConfDirective*>      get_transcode_engines(SrsConfDirective* transcode);/*** whether the engine is enabled.*/virtual bool                get_engine_enabled(SrsConfDirective* engine);/*** get the iformat of engine*/virtual std::string         get_engine_iformat(SrsConfDirective* engine);/*** get the vfilter of engine,* the video filter set before the vcodec of FFMPEG.*/virtual std::vector<std::string> get_engine_vfilter(SrsConfDirective* engine);/*** get the vcodec of engine,* the codec of video, can be vn, copy or libx264*/virtual std::string         get_engine_vcodec(SrsConfDirective* engine);/*** get the vbitrate of engine,* the bitrate in kbps of video, for example, 800kbps*/virtual int                 get_engine_vbitrate(SrsConfDirective* engine);/*** get the vfps of engine.* the video fps, for example, 25fps*/virtual double              get_engine_vfps(SrsConfDirective* engine);/*** get the vwidth of engine,* the video width, for example, 1024*/virtual int                 get_engine_vwidth(SrsConfDirective* engine);/*** get the vheight of engine,* the video height, for example, 576*/virtual int                 get_engine_vheight(SrsConfDirective* engine);/*** get the vthreads of engine,* the video transcode libx264 threads, for instance, 8*/virtual int                 get_engine_vthreads(SrsConfDirective* engine);/*** get the vprofile of engine,* the libx264 profile, can be high,main,baseline*/virtual std::string         get_engine_vprofile(SrsConfDirective* engine);/*** get the vpreset of engine,* the libx264 preset, can be ultrafast,superfast,veryfast,faster,fast,medium,slow,slower,veryslow,placebo*/virtual std::string         get_engine_vpreset(SrsConfDirective* engine);/*** get the additional video params.*/virtual std::vector<std::string> get_engine_vparams(SrsConfDirective* engine);/*** get the acodec of engine,* the audio codec can be an, copy or libfdk_aac*/virtual std::string         get_engine_acodec(SrsConfDirective* engine);/*** get the abitrate of engine,* the audio bitrate in kbps, for instance, 64kbps.*/virtual int                 get_engine_abitrate(SrsConfDirective* engine);/*** get the asample_rate of engine,* the audio sample_rate, for instance, 44100HZ*/virtual int                 get_engine_asample_rate(SrsConfDirective* engine);/*** get the achannels of engine,* the audio channel, for instance, 1 for mono, 2 for stereo.*/virtual int                 get_engine_achannels(SrsConfDirective* engine);/*** get the aparams of engine,* the audio additional params.*/virtual std::vector<std::string> get_engine_aparams(SrsConfDirective* engine);/*** get the oformat of engine*/virtual std::string         get_engine_oformat(SrsConfDirective* engine);/*** get the output of engine, for example, rtmp://localhost/live/livestream,* @remark, we will use some variable, for instance, [vhost] to substitude with vhost.*/virtual std::string         get_engine_output(SrsConfDirective* engine);
// vhost ingest section
public:/*** get the ingest directives of vhost.*/virtual std::vector<SrsConfDirective*> get_ingesters(std::string vhost);/*** get specified ingest.*/virtual SrsConfDirective*   get_ingest_by_id(std::string vhost, std::string ingest_id);/*** whether ingest is enalbed.*/virtual bool                get_ingest_enabled(SrsConfDirective* ingest);/*** get the ingest ffmpeg tool*/virtual std::string         get_ingest_ffmpeg(SrsConfDirective* ingest);/*** get the ingest input type, file or stream.*/virtual std::string         get_ingest_input_type(SrsConfDirective* ingest);/*** get the ingest input url.*/virtual std::string         get_ingest_input_url(SrsConfDirective* ingest);
// log section
public:/*** whether log to file.*/virtual bool                get_log_tank_file();/*** get the log level.*/virtual std::string         get_log_level();/*** get the log file path.*/virtual std::string         get_log_file();/*** whether ffmpeg log enabled*/virtual bool                get_ffmpeg_log_enabled();/*** the ffmpeg log dir.* @remark, /dev/null to disable it.*/virtual std::string         get_ffmpeg_log_dir();
// hls section
private:/*** get the hls directive of vhost.*/virtual SrsConfDirective*   get_hls(std::string vhost);
public:/*** whether HLS is enabled.*/virtual bool                get_hls_enabled(std::string vhost);/*** get the HLS m3u8 list ts segment entry prefix info.*/virtual std::string         get_hls_entry_prefix(std::string vhost);/*** get the HLS ts/m3u8 file store path.*/virtual std::string         get_hls_path(std::string vhost);/*** get the HLS m3u8 file path template.*/virtual std::string         get_hls_m3u8_file(std::string vhost);/*** get the HLS ts file path template.*/virtual std::string         get_hls_ts_file(std::string vhost);/*** whether enable the floor(timestamp/hls_fragment) for variable timestamp.*/virtual bool                get_hls_ts_floor(std::string vhost);/*** get the hls fragment time, in seconds.*/virtual double              get_hls_fragment(std::string vhost);/*** get the hls td(target duration) ratio.*/virtual double              get_hls_td_ratio(std::string vhost);/*** get the hls aof(audio overflow) ratio.*/virtual double              get_hls_aof_ratio(std::string vhost);/*** get the hls window time, in seconds.* a window is a set of ts, the ts collection in m3u8.* @remark SRS will delete the ts exceed the window.*/virtual double              get_hls_window(std::string vhost);/*** get the hls hls_on_error config.* the ignore will ignore error and disable hls.* the disconnect will disconnect publish connection.* @see https://github.com/ossrs/srs/issues/264*/virtual std::string         get_hls_on_error(std::string vhost);/*** get the HLS default audio codec.*/virtual std::string         get_hls_acodec(std::string vhost);/*** get the HLS default video codec.*/virtual std::string         get_hls_vcodec(std::string vhost);/*** whether cleanup the old ts files.*/virtual bool                get_hls_cleanup(std::string vhost);/*** the timeout to dispose the hls.*/virtual int                 get_hls_dispose(std::string vhost);/*** whether reap the ts when got keyframe.*/virtual bool                get_hls_wait_keyframe(std::string vhost);/*** get the size of bytes to read from cdn network, for the on_hls_notify callback,* that is, to read max bytes of the bytes from the callback, or timeout or error.*/virtual int                 get_vhost_hls_nb_notify(std::string vhost);
// hds section
private:/*** get the hds directive of vhost.*/virtual SrsConfDirective*   get_hds(const std::string &vhost);
public:/*** whether HDS is enabled.*/virtual bool                get_hds_enabled(const std::string &vhost);/*** get the HDS file store path.*/virtual std::string         get_hds_path(const std::string &vhost);/*** get the hds fragment time, in seconds.*/virtual double              get_hds_fragment(const std::string &vhost);/*** get the hds window time, in seconds.* a window is a set of hds fragments.*/virtual double              get_hds_window(const std::string &vhost);// dvr section
private:/*** get the dvr directive.*/virtual SrsConfDirective*   get_dvr(std::string vhost);
public:/*** whether dvr is enabled.*/virtual bool                get_dvr_enabled(std::string vhost);/*** get the dvr path, the flv file to save in.*/virtual std::string         get_dvr_path(std::string vhost);/*** get the plan of dvr, how to reap the flv file.*/virtual std::string         get_dvr_plan(std::string vhost);/*** get the duration of dvr flv.*/virtual int                 get_dvr_duration(std::string vhost);/*** whether wait keyframe to reap segment.*/virtual bool                get_dvr_wait_keyframe(std::string vhost);/*** get the time_jitter algorithm for dvr.*/virtual int                 get_dvr_time_jitter(std::string vhost);
// http api section
private:/*** get the http api directive.*/virtual SrsConfDirective*   get_http_api();/*** whether http api enabled*/virtual bool                get_http_api_enabled(SrsConfDirective* conf);
public:/*** whether http api enabled.*/virtual bool                get_http_api_enabled();/*** get the http api listen port.*/virtual std::string         get_http_api_listen();/*** whether enable crossdomain for http api.*/virtual bool                get_http_api_crossdomain();
// http stream section
private:/*** get the http stream directive.*/virtual SrsConfDirective*   get_http_stream();/*** whether http stream enabled.*/virtual bool                get_http_stream_enabled(SrsConfDirective* conf);
public:/*** whether http stream enabled.*/virtual bool                get_http_stream_enabled();/*** get the http stream listen port.*/virtual std::string         get_http_stream_listen();/*** get the http stream root dir.*/virtual std::string         get_http_stream_dir();
public:/*** get whether vhost enabled http stream*/virtual bool                get_vhost_http_enabled(std::string vhost);/*** get the http mount point for vhost.* for example, http://vhost/live/livestream*/virtual std::string         get_vhost_http_mount(std::string vhost);/*** get the http dir for vhost.* the path on disk for mount root of http vhost.*/virtual std::string         get_vhost_http_dir(std::string vhost);
// flv live streaming section
public:/*** get whether vhost enabled http flv live stream*/virtual bool                get_vhost_http_remux_enabled(std::string vhost);/*** get the fast cache duration for http audio live stream.*/virtual double              get_vhost_http_remux_fast_cache(std::string vhost);/*** get the http flv live stream mount point for vhost.* used to generate the flv stream mount path.*/virtual std::string         get_vhost_http_remux_mount(std::string vhost);/*** get whether the hstrs(http stream trigger rtmp source) enabled.*/virtual bool                get_vhost_http_remux_hstrs(std::string vhost);
// http heartbeart section
private:/*** get the heartbeat directive.*/virtual SrsConfDirective*   get_heartbeart();
public:/*** whether heartbeat enabled.*/virtual bool                get_heartbeat_enabled();/*** get the heartbeat interval, in ms.*/virtual int64_t             get_heartbeat_interval();/*** get the heartbeat report url.*/virtual std::string         get_heartbeat_url();/*** get the device id of heartbeat, to report to server.*/virtual std::string         get_heartbeat_device_id();/*** whether report with summaries of http api: /api/v1/summaries.*/virtual bool                get_heartbeat_summaries();
// stats section
private:/*** get the stats directive.*/virtual SrsConfDirective*   get_stats();
public:/*** get the network device index, used to retrieve the ip of device,* for heartbeat to report to server, or to get the local ip.* for example, 0 means the eth0 maybe.*/virtual int                 get_stats_network();/*** get the disk stat device name list.* the device name configed in args of directive.* @return the disk device name to stat. NULL if not configed.*/virtual SrsConfDirective*   get_stats_disk_device();
};

1.2 SrsConfDirective 类

/**
* the config directive.
* the config file is a group of directives,
* all directive has name, args and child-directives.
* for example, the following config text:vhost vhost.ossrs.net {enabled         on;ingest livestream {enabled      on;ffmpeg       /bin/ffmpeg;}}
* will be parsed to:
*       SrsConfDirective: name="vhost", arg0="vhost.ossrs.net", child-directives=[
*           SrsConfDirective: name="enabled", arg0="on", child-directives=[]
*           SrsConfDirective: name="ingest", arg0="livestream", child-directives=[
*               SrsConfDirective: name="enabled", arg0="on", child-directives=[]
*               SrsConfDirective: name="ffmpeg", arg0="/bin/ffmpeg", child-directives=[]
*           ]
*       ]
* @remark, allow empty directive, for example: "dir0 {}"
* @remark, don't allow empty name, for example: ";" or "{dir0 arg0;}
*/
class SrsConfDirective
{
public:/*** the line of config file in which the directive from*/int conf_line;/*** the name of directive, for example, the following config text:*       enabled     on;* will be parsed to a directive, its name is "enalbed"*/std::string name;/*** the args of directive, for example, the following config text:*       listen      1935 1936;* will be parsed to a directive, its args is ["1935", "1936"].*/std::vector<std::string> args;/*** the child directives, for example, the following config text:*       vhost vhost.ossrs.net {*           enabled         on;*       }* will be parsed to a directive, its directives is a vector contains * a directive, which is:*       name:"enalbed", args:["on"], directives:[]* * @remark, the directives can contains directives.*/std::vector<SrsConfDirective*> directives;
public:SrsConfDirective();virtual ~SrsConfDirective();
// args
public:/*** get the args0,1,2, if user want to get more args,* directly use the args.at(index).*/virtual std::string arg0();virtual std::string arg1();virtual std::string arg2();
// directives
public:/*** get the directive by index.* @remark, assert the index<directives.size().*/virtual SrsConfDirective* at(int index);/*** get the directive by name, return the first match.*/virtual SrsConfDirective* get(std::string _name);/*** get the directive by name and its arg0, return the first match.*/virtual SrsConfDirective* get(std::string _name, std::string _arg0);
// help utilities
public:/*** whether current directive is vhost.*/virtual bool is_vhost();/*** whether current directive is stream_caster.*/virtual bool is_stream_caster();
// parse utilities
public:/*** parse config directive from file buffer.*/virtual int parse(_srs_internal::SrsConfigBuffer* buffer);
// private parse.
private:/*** the directive parsing type.*/enum SrsDirectiveType {/*** the root directives, parsing file.*/parse_file, /*** for each direcitve, parsing text block.*/parse_block};/*** parse the conf from buffer. the work flow:* 1. read a token(directive args and a ret flag), * 2. initialize the directive by args, args[0] is name, args[1-N] is args of directive,* 3. if ret flag indicates there are child-directives, read_conf(directive, block) recursively.*/virtual int parse_conf(_srs_internal::SrsConfigBuffer* buffer, SrsDirectiveType type);/*** read a token from buffer.* a token, is the directive args and a flag indicates whether has child-directives.* @param args, the output directive args, the first is the directive name, left is the args.* @param line_start, the actual start line of directive.* @return, an error code indicates error or has child-directives.*/virtual int read_token(_srs_internal::SrsConfigBuffer* buffer, std::vector<std::string>& args, int& line_start);
};

1.3 SrsConfigBuffer

namespace _srs_internal
{class SrsConfigBuffer;
}namespace _srs_internal
{/*** the buffer of config content.*/class SrsConfigBuffer{protected:// last available position.char* last;// end of buffer.char* end;// start of buffer.char* start;public:// current consumed position.char* pos;// current parsed line.int line;public:SrsConfigBuffer();virtual ~SrsConfigBuffer();public:/*** fullfill the buffer with content of file specified by filename.*/virtual int fullfill(const char* filename);/*** whether buffer is empty.*/virtual bool empty();};
};

2. 函数实现

2.1 SrsConfig::parse_options

// see: ngx_get_options
int SrsConfig::parse_options(int argc, char** argv)
{int ret = ERROR_SUCCESS;// argv: 将 argv 中的数据拷贝到 _argv 中,多个字符串之间以 " " 间隔for (int i = 0; i < argc; i++) {_argv.append(argv[i]);if (i < argc - 1) {_argv.append(" ");}}// config: 解析通过命令行传入的参数show_help = true;for (int i = 1; i < argc; i++) {if ((ret = parse_argv(i, argv)) != ERROR_SUCCESS) {return ret;}}if (show_help) {print_help(argv);exit(0);}if (show_version) {fprintf(stderr, "%s\n", RTMP_SIG_SRS_VERSION);exit(0);}// first hello message.srs_trace(_srs_version);if (config_file.empty()) {ret = ERROR_SYSTEM_CONFIG_INVALID;srs_error("config file not specified, see help: %s -h, ret=%d", argv[0], ret);return ret;}// 解析配置文件ret = parse_file(config_file.c_str());if (test_conf) {// the parse_file never check the config,// we check it when user requires check config file.if (ret == ERROR_SUCCESS) {ret = check_ocnfig();}if (ret == ERROR_SUCCESS) {srs_trace("config file is ok");exit(0);} else {srs_error("config file is invalid");exit(ret);}}// check log name and levelif (true) {/* 从 root 指令中获取"srs_log_file"指令指定的log文件路径,若没有找到,* 则使用默认log文件: "./objs/srs.log" */std::string log_filename = this->get_log_file();if (get_log_tank_file() && log_filename.empty()) {ret = ERROR_SYSTEM_CONFIG_INVALID;srs_error("must specifies the file to write log to. ret=%d", ret);return ret;}// 将日志保存到文件中if (get_log_tank_file()) {srs_trace("write log to file %s", log_filename.c_str());srs_trace("you can: tailf %s", log_filename.c_str());srs_trace("@see: %s", SRS_WIKI_URL_LOG);} else { // 否则,将日志打印到 console 中srs_trace("write log to console");}}
}

2.2 SrsConfig::parse_argv

int SrsConfig::parse_argv(int& i, char** argv)
{int ret = ERROR_SUCCESS;char* p = argv[i];if (*p++ != '-') {show_help = true;return ret;}while (*p) {switch (*p++) {case '?':case 'h':show_help = true;break;case 't':show_help = false;test_conf = true;break;case 'p':dolphin = true;if (*p) {dolphin_rtmp_port = p;continue;}if (argv[++i]) {dolphin_rtmp_port = argv[i];continue;}ret = ERROR_SYSTEM_CONFIG_INVALID;srs_error("option \"-p\" requires params, ret=%d", ret);return ret;case 'x':dolphin = true;if (*p) {dolphin_http_port = p;continue;}if (argv[++i]) {dolphin_http_port = argv[i];continue;}ret = ERROR_SYSTEM_CONFIG_INVALID;srs_error("option \"-x\" requires params, ret=%d", ret);return ret;case 'v':case 'V':show_help = false;show_version = true;break;case 'c':show_help = false;if (*p) {config_file = p;continue;}if (argv[++i]) {config_file = argv[i];continue;}ret = ERROR_SYSTEM_CONFIG_INVALID;srs_error("option \"-c\" requires parameter, ret=%d", ret);return ret;default:ret = ERROR_SYSTEM_CONFIG_INVALID;srs_error("invalid option: \"%c\", see help: %s -h, ret=%d", *(p - 1), argv[0], ret);return ret;}}return ret;
}

2.3 SrsConfig::parse_file

int SrsConfig::parse_file(const char *filename)
{int ret = ERROR_SUCCESS;config_file = filename;if (config_file.empty()) {return ERROR_SYSTEM_CONFIG_INVALID;}// 构造一个 SrsConfigBuffer 类的变量,用于存放配置文件的内容SrsConfigBuffer buffer;// 将配置文件的内容填充到 buffer 缓存中if ((ret = buffer.fullfill(config_file.c_str())) != ERROR_SUCCESS) {return ret;}// 解析 buffer 中的配置项return parse_buffer(&buffer);
}

2.4 namespace _srs_internal

namespace _srs_internal
{SrsConfigBuffer::SrsConfigBuffer(){line = 1;pos = last = start = NULL;end = start;}SrsConfigBuffer::~SrsConfigBuffer(){srs_freepa(start);}int SrsConfigBuffer::fullfill(const char *filename) {int ret = ERROR_SUCCESS;SrsFileReader reader;// open file reader.if ((ret = reader.open(filename)) != ERROR_SUCCESS) {srs_error("open conf file error. ret=%d", ret);return ret;}// read all.int filesize = (int)reader.filesize();// create buffersrs_freepa(start);pos = last = start = new char[filesize];end = start + filesize;// read total content from file.ssize_t nread = 0;if ((ret = reader.read(start, filesize, &nread)) != ERROR_SUCCESS) {srs_error("read file read error. expect %d, actual %d bytes, ret=%d", filesize, nread, ret);return ret;}return ret;}bool SrsConfigBuffer::empty(){return pos >= end;}
}

2.5 SrsConfig::parse_buffer

int SrsConfig::parse_buffer(SrsConfigBuffer* buffer)
{int ret = ERROR_SUCCESS;/* 解析 buffer 中的配置,解析出来的配置值保存在 root 指令中,* root 构建了一个指令树,保存着配置文件中所有指令 */if ((ret = root->parse(buffer)) != ERROR_SUCCESS) {return ret;}// mock by dolphin mode.// for the dolphin will start srs with specified params.if (dolphin) {// for RTMP.set_config_directive(root, "listen", dolphin_rtmp_port);// for HTTP.set_config_directive(root, "http_server", "");SrsConfDirective* http_server = root->get("http_server");set_config_directive(http_server, "enabled", "on");set_config_directive(http_server, "listen", dolphin_http_port);// others.set_config_directive(root, "daemon", "off");set_config_directive(root, "srs_log_tank", "console");}return ret;
}

2.5.1 SrsConfig::set_config_directive

void SrsConfig::set_config_directive(SrsConfDirective* parent, string dir, string value)
{// 尝试从 parent 中获取该 dir 指令SrsConfDirective* d = parent->get(dir);// 若 parent 指令中没有该 dir 子指令,则创建一个新指令if (!d) {d = new SrsConfDirective();if (!dir.empty()) {d->name = dir;}parent->directive.push_back(d);}// 清空该指令的参数d->args.clear();if (!value.empty) {d->args.push_back(value);}
}

2.6 SrsConfDirective::parse

int SrsConfDirective::parse(SrsConfigBuffer* buffer)
{// parse_file 表示当前开始解析配置文件return parse_conf(buffer, parse_file);
}

2.7 SrsConfDirective::parse_conf

// see: ngx_conf_parse
int SrsConfDirective::parse_conf(SrsConfigBuffer* buffer, SrsDirectiveType type)
{int ret = ERROR_SUCCESS;while (true) {std::vector<string> args;int line_start = 0;// 读取一行内容ret = read_token(buffer, args, line_start);/*** ret maybe:* ERROR_SYSTEM_CONFIG_INVALID           error.* ERROR_SYSTEM_CONFIG_DIRECTIVE         directive terminated by ';' found* ERROR_SYSTEM_CONFIG_BLOCK_START       token terminated by '{' found* ERROR_SYSTEM_CONFIG_BLOCK_END         the '}' found* ERROR_SYSTEM_CONFIG_EOF               the config file is done*/if (ret == ERROR_SYSTEM_CONFIG_INVALID) {return ret;}if (ret == ERROR_SYSTEM_CONFIG_BLOCK_END) {if (type != parse_block) {srs_error("line: %d: unexpected \"}\", ret=%d", buffer->line, ret);return ret;}return ERROR_SUCCESS;}if (ret == ERROR_SYSTEM_CONFIG_EOF) {if (type == parse_block) {srs_error("line %d: unexpected end of file, expecting \"}\", ret=%d", conf_line, ret);return ret;}return ERROR_SUCCESS;}// 若没有读取到任何数据,则表示出错了if (args.empty()) {ret = ERROR_SYSTEM_CONFIG_INVALID;srs_error("line %d: empty directive. ret=%d", conf_line, ret);return ret;}// build directive tree.SrsConfDirective* directive = new SrsConfDirective();directive->conf_line = line_start;directive->name = args[0];// 将 args[0] 从 args vector 容器中删除args.erase(args.begin());/* 将 args 中的全部数据和 directive->args 中的数据进行交换,* 即相等于将 args 中的数据拷贝给 directive->args */directive->args.swap(args);// 将该新解析的指令放入到 vector 类的 directives 容器中directives.push_back(directive);// 若为一个配置块的开始,则递归调用 parse_conf if (ret == ERROR_SYSTEM_CONFIG_BLOCK_START) {if ((ret = directive->parse_conf(buffer, parse_block) != ERROR_SUCCESS) {return ret;}}}return ret;
}

2.8 SrsConfDirective::read_token

// see: ngx_conf_read_token
int SrsConfDirective::read_token(SrsConfigBuffer* buffer, vector<string>& args, int& line_start)
{int ret = ERROR_SUCCESS;char* pstart = buffer->pos;// 若为 true,表示当前行是注释bool sharp_comment = false;// 若为 true,表示当前字符是 双引号 "bool d_quoted = false;// 若为 true,表示当前字符是 单引号 'bool s_quoted = false;// 若为 true,表示下一个的字符必须是空格bool need_space = false;// 若为 true,表示当前字符是最后一个空格,即下一个字符不是空格了bool last_space = true;while (true) {if (buffer->empty()) {ret = ERROR_SYSTEM_CONFIG_EOF;if (!args.empty() || !last_space) {srs_error("line %d: unexpected end of file, expecting ; or \"}\"", buffer->line);return ERROR_SYSTEM_CONFIG_INVALID;}srs_trace("config parse complete");return ret;}char ch = *buffer->pos++;// 若当前字符为 换行符,则表示当前行结束if (ch == SRS_LF) {buffer->line++;sharp_comment = false;}// 表示遇到注释了if (sharp_comment) {continue;}if (need_space) {if (is_common_space(ch)) {last_space = true;need_space = false;continue;}if (ch == ';') {return ERROR_SYSTEM_CONFIG_DIRECTIVE;}if (ch == '{') {return ERROR_SYSTEM_CONFIG_BLOCK_START;}srs_error("line %d: unexpected '%c'", buffer->line, ch);return ERROR_SYSTEM_CONFIG_INVALID; }// last charecter is space.if (last_space) {// 若当前字符是空格,则继续取下一个字符if (is_common_space(ch)) {continue;}pstart = buffer->pos - 1;switch (ch) {case ';':if (args.size() == 0) {srs_error("line %d: unexpected ';'", buffer->line);return ERROR_SYSTEM_CONFIG_INVALID;}return ERROR_SYSTEM_CONFIG_DIRECTIVE;case '{':if (args.size() == 0) {srs_error("line %d: unexpected '{'", buffer->line);return ERROR_SYSTEM_CONFIG_INVALID;}return ERROR_SYSTEM_CONFIG_BLOCK_START;case '}':if (args.size() != 0) {srs_error("line %d: unexpected '}'", buffer->line);return ERROR_SYSTEM_CONFIG_INVALID;}return ERROR_SYSTEM_CONFIG_BLOCK_END;case '#':sharp_comment = 1;continue;case '"':pstart++;d_quoted = true;last_space = 0;continue;case '\'':pstart++;s_quoted = true;last_space = 0;continue;default:last_space = 0;continue;}} else {// last charecter is not spaceif (line_start == 0) {line_start = buffer->line;}bool found = false;if (d_quoted) {if (ch == '"') {d_quoted = false;need_space = true;found = true;}} else if (s_quoted) {if (ch == '\'') {s_quoted = false;need_space = true;found = true;}// 若当前字符是空格 或 ; 或 {,则置位 found} else if (is_common_space(ch) || ch == ';' || ch == '{') {last_space = true;found = 1;}if (found) {int len = (int)(buffer->pos - pstart);char* aword = new char[len];memcpy(aword, pstart, len);aword[len - 1] = 0;// 将其放入到 vector 类型的 args 容器中string word_str = aword;if (!word_str.empty()) {args.push_back(word_str);}srs_freepa(aword);if (ch == ';') {return ERROR_SYSTEM_CONFIG_DIRECTIVE;}if (ch == '{') {return ERROR_SYSTEM_CONFIG_BLOCK_START;}}}}return ret;
}

2.9 SrsConfig::subscribe

void SrsConfig::subscribe(ISrsReloadHandler* handler)
{std::vector<ISrsReloadHandler*>::iterator it;/* 在 subscribes 容器中查找到与 handler 等值的第一个元素的迭代器,* 若遍历完都没有找到,则将该 handler 放入到 subscribes 容器的末尾 */it = std::find(subscribes.begin(), subscribes.end(), handler);if (it != subscribes.end()) {return;}subscribes.push_back(handler);
}

转载于:https://www.cnblogs.com/jimodetiantang/p/9013794.html

SRS之SrsConfig类相关推荐

  1. 使用gdb分析coredump文件排查流媒体服务srs偶发内存泄漏问题

    内存泄漏 正常情况内存消耗比较平稳,但是异常后如下图可以看到内存在几个小时内内存消耗殆尽导致操作系统直接kill掉srs进程 排查难点 内存泄漏是偶发的这是排查的难点,如果是必现可以借助一些成熟的工具 ...

  2. 自己搜集编写的Delphi 通用函数

    { ********************************************************************** } { Currency Common Functio ...

  3. SRS学习笔记7-SrsHttpServer

    the http server, use http stream or static server to serve requests. 源代码位置: app\srs_app_http_conn.hp ...

  4. srs10流程图_高效的SRS资源指示方法与流程

    公开的主题一般涉及电信,更特别地涉及下一代移动无线通信系统中的srs资源的高效指示. 背景技术: 下一代移动无线通信系统(5g或nr)将支持各种用例集合和各种部署场景集合.后者包括在低频(数百mhz) ...

  5. 音视频开发为什么要学SRS流媒体服务器

    1 SRS是什么 官方定义:SRS是一个流媒体集群,支持RTMP/HLS/HTTP-FLV/RTSP/DASH/WebRTC/SRT/GB28181,高效.稳定.易用,简单而快乐.有将近10k sta ...

  6. SRS后需求双向追溯解决方法

    说来也很简单. 常见的是利用工具(有专门的,也有用ACCESS,EXCEL,或定制)来得到一个需求矩阵的. 这里介绍一种最简单的方法. 1,在SRS中划分出一个一个需求,比如功能点,画面,条目等等,给 ...

  7. mave工程中的一个类调用另一个聚合工程的一个类_信息系统管理工程师备考分享(材料重点精炼)——第一章信息化和信息系统(4)...

    本章分享的1.4节的重要考点内容相对来说还是比较多的,里面包括需求.设计.测试等软件工程的内容,同学们学完前几篇文章的分享会发现,第一章与计算机领域的知识的衔接程度还是非常紧密的.我经常会听到很多面授 ...

  8. SRS流媒体服务器——Forward集群搭建和源码分析

    SRS流媒体服务器--Forward集群搭建和源码分析 目录 Forward集群原理 RTMP流转发(Forward)部署实例 Forward集群源码分析 1. Forward集群原理 Forward ...

  9. SRS流媒体服务器——单机环境搭建和源码目录介绍

    SRS流媒体服务器--单机环境搭建和源码目录介绍 1. 目录 环境搭建 源码目录介绍 1. 环境搭建 srs官⽹:https://github.com/ossrs/srs 码云的源速度快:https: ...

最新文章

  1. 如何使用 Arthas 定位 Spring Boot 接口超时 ?
  2. SQL CASE When THEN END 行列转换,复杂查询
  3. 厚积薄发,拥抱 .NET 2016
  4. 小米登录协议分析_小米温湿度传感器协议分析
  5. 将 Citavi 笔记按需要导出
  6. Java 新手习题()
  7. 阿里面试官给你的一些忠告,这样做肯定错不了!附视频
  8. 如何玩转小程序+公众号?手把手教你JeeWx小程序CMS与公众号关联
  9. Android开发(二十四)——数据存储SharePreference、SQLite、File、ContentProvider
  10. android如何用代码实现界面ui
  11. 编写一个链表结构关于车的属性,读取任意多辆车的车型、车牌号、外形颜色、价钱输入。之后遍历链表,再将链表数据打印出来。
  12. RabbitMQ下载与安装
  13. 网络基础该从哪开始补?这36张图,一次性理清
  14. python对月饼数据进行可视化,看看哪家最划算
  15. React将字符串转化成组件,将Antd图标字符串转化为图标组件
  16. 网站页面上标签页小图标的添加方式
  17. 登陆时做下双因子验证
  18. Go语言 rand(随机数)包
  19. 【Python网络爬虫】百度贴吧/豆瓣小组
  20. 泊松抽样与伯努利抽样主要联系与区别

热门文章

  1. 目前UI设计和前端哪个行业更好,女生应该怎么抉择?
  2. Troubleshooting: WAITED TOO LONG FOR A ROW CACHE ENQUEUE LOCK! (文档 ID 278316.1)
  3. 【优化】利普希茨连续(Lipschitz continuous)及其应用
  4. Lipschitz型函数
  5. 社工库寻求帮助可以下载
  6. 21计算机考研国家线,来了!21考研国家线公布!附详细解读!
  7. 中学计算机论文题目,中学计算机相关论文题目 中学计算机论文标题如何定
  8. ValueError: A 0.7-series setuptools cannot be installed with distribute.
  9. ArcMap 属性连接和空间连接用法
  10. Java从服务端下载Excel模板文件