winlin

implements ingest, change to 0.9.53

@@ -104,7 +104,8 @@ vhost ingest.srs.com { @@ -104,7 +104,8 @@ vhost ingest.srs.com {
104 # can be file/stream/device, that is, 104 # can be file/stream/device, that is,
105 # file: ingest file specifies by url. 105 # file: ingest file specifies by url.
106 # stream: ingest stream specifeis by url. 106 # stream: ingest stream specifeis by url.
107 - # devide: not support yet. 107 + # device: not support yet.
  108 + # default: file
108 type file; 109 type file;
109 # the url of file/stream. 110 # the url of file/stream.
110 url ./doc/source.200kbps.768x320.flv; 111 url ./doc/source.200kbps.768x320.flv;
@@ -810,6 +811,9 @@ pithy_print { @@ -810,6 +811,9 @@ pithy_print {
810 # shared print interval for all encoders, in milliseconds. 811 # shared print interval for all encoders, in milliseconds.
811 # if not specified, set to 2000. 812 # if not specified, set to 2000.
812 encoder 3000; 813 encoder 3000;
  814 + # shared print interval for all ingesters, in milliseconds.
  815 + # if not specified, set to 2000.
  816 + ingester 3000;
813 # shared print interval for all hls, in milliseconds. 817 # shared print interval for all hls, in milliseconds.
814 # if not specified, set to 2000. 818 # if not specified, set to 2000.
815 hls 3000; 819 hls 3000;
@@ -847,12 +847,12 @@ int SrsConfig::get_pithy_print_forwarder() @@ -847,12 +847,12 @@ int SrsConfig::get_pithy_print_forwarder()
847 847
848 int SrsConfig::get_pithy_print_encoder() 848 int SrsConfig::get_pithy_print_encoder()
849 { 849 {
850 - SrsConfDirective* pithy = root->get("encoder"); 850 + SrsConfDirective* pithy = root->get("pithy_print");
851 if (!pithy) { 851 if (!pithy) {
852 return SRS_STAGE_ENCODER_INTERVAL_MS; 852 return SRS_STAGE_ENCODER_INTERVAL_MS;
853 } 853 }
854 854
855 - pithy = pithy->get("forwarder"); 855 + pithy = pithy->get("encoder");
856 if (!pithy) { 856 if (!pithy) {
857 return SRS_STAGE_ENCODER_INTERVAL_MS; 857 return SRS_STAGE_ENCODER_INTERVAL_MS;
858 } 858 }
@@ -860,6 +860,21 @@ int SrsConfig::get_pithy_print_encoder() @@ -860,6 +860,21 @@ int SrsConfig::get_pithy_print_encoder()
860 return ::atoi(pithy->arg0().c_str()); 860 return ::atoi(pithy->arg0().c_str());
861 } 861 }
862 862
  863 +int SrsConfig::get_pithy_print_ingester()
  864 +{
  865 + SrsConfDirective* pithy = root->get("pithy_print");
  866 + if (!pithy) {
  867 + return SRS_STAGE_INGESTER_INTERVAL_MS;
  868 + }
  869 +
  870 + pithy = pithy->get("ingester");
  871 + if (!pithy) {
  872 + return SRS_STAGE_INGESTER_INTERVAL_MS;
  873 + }
  874 +
  875 + return ::atoi(pithy->arg0().c_str());
  876 +}
  877 +
863 int SrsConfig::get_pithy_print_hls() 878 int SrsConfig::get_pithy_print_hls()
864 { 879 {
865 SrsConfDirective* pithy = root->get("pithy_print"); 880 SrsConfDirective* pithy = root->get("pithy_print");
@@ -1645,11 +1660,34 @@ string SrsConfig::get_ingest_ffmpeg(SrsConfDirective* ingest) @@ -1645,11 +1660,34 @@ string SrsConfig::get_ingest_ffmpeg(SrsConfDirective* ingest)
1645 return conf->arg0(); 1660 return conf->arg0();
1646 } 1661 }
1647 1662
1648 -string SrsConfig::get_ingest_input(SrsConfDirective* ingest) 1663 +string SrsConfig::get_ingest_input_type(SrsConfDirective* ingest)
1649 { 1664 {
1650 SrsConfDirective* conf = ingest->get("input"); 1665 SrsConfDirective* conf = ingest->get("input");
1651 1666
1652 if (!conf) { 1667 if (!conf) {
  1668 + return SRS_INGEST_TYPE_FILE;
  1669 + }
  1670 +
  1671 + conf = conf->get("type");
  1672 +
  1673 + if (!conf) {
  1674 + return SRS_INGEST_TYPE_FILE;
  1675 + }
  1676 +
  1677 + return conf->arg0();
  1678 +}
  1679 +
  1680 +string SrsConfig::get_ingest_input_url(SrsConfDirective* ingest)
  1681 +{
  1682 + SrsConfDirective* conf = ingest->get("input");
  1683 +
  1684 + if (!conf) {
  1685 + return "";
  1686 + }
  1687 +
  1688 + conf = conf->get("url");
  1689 +
  1690 + if (!conf) {
1653 return ""; 1691 return "";
1654 } 1692 }
1655 1693
@@ -66,8 +66,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -66,8 +66,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
66 #define SRS_STAGE_PUBLISH_USER_INTERVAL_MS 1100 66 #define SRS_STAGE_PUBLISH_USER_INTERVAL_MS 1100
67 #define SRS_STAGE_FORWARDER_INTERVAL_MS 2000 67 #define SRS_STAGE_FORWARDER_INTERVAL_MS 2000
68 #define SRS_STAGE_ENCODER_INTERVAL_MS 2000 68 #define SRS_STAGE_ENCODER_INTERVAL_MS 2000
  69 +#define SRS_STAGE_INGESTER_INTERVAL_MS 2000
69 #define SRS_STAGE_HLS_INTERVAL_MS 2000 70 #define SRS_STAGE_HLS_INTERVAL_MS 2000
70 71
  72 +#define SRS_INGEST_TYPE_FILE "file"
  73 +
71 class SrsFileBuffer; 74 class SrsFileBuffer;
72 75
73 class SrsConfDirective 76 class SrsConfDirective
@@ -134,6 +137,7 @@ public: @@ -134,6 +137,7 @@ public:
134 virtual int get_pithy_print_publish(); 137 virtual int get_pithy_print_publish();
135 virtual int get_pithy_print_forwarder(); 138 virtual int get_pithy_print_forwarder();
136 virtual int get_pithy_print_encoder(); 139 virtual int get_pithy_print_encoder();
  140 + virtual int get_pithy_print_ingester();
137 virtual int get_pithy_print_hls(); 141 virtual int get_pithy_print_hls();
138 virtual int get_pithy_print_play(); 142 virtual int get_pithy_print_play();
139 // vhost section 143 // vhost section
@@ -190,7 +194,8 @@ public: @@ -190,7 +194,8 @@ public:
190 virtual void get_ingesters(std::string vhost, std::vector<SrsConfDirective*>& ingeters); 194 virtual void get_ingesters(std::string vhost, std::vector<SrsConfDirective*>& ingeters);
191 virtual bool get_ingest_enabled(SrsConfDirective* ingest); 195 virtual bool get_ingest_enabled(SrsConfDirective* ingest);
192 virtual std::string get_ingest_ffmpeg(SrsConfDirective* ingest); 196 virtual std::string get_ingest_ffmpeg(SrsConfDirective* ingest);
193 - virtual std::string get_ingest_input(SrsConfDirective* ingest); 197 + virtual std::string get_ingest_input_type(SrsConfDirective* ingest);
  198 + virtual std::string get_ingest_input_url(SrsConfDirective* ingest);
194 // log section 199 // log section
195 public: 200 public:
196 virtual bool get_srs_log_tank_file(); 201 virtual bool get_srs_log_tank_file();
@@ -99,13 +99,13 @@ int SrsEncoder::cycle() @@ -99,13 +99,13 @@ int SrsEncoder::cycle()
99 99
100 // start all ffmpegs. 100 // start all ffmpegs.
101 if ((ret = ffmpeg->start()) != ERROR_SUCCESS) { 101 if ((ret = ffmpeg->start()) != ERROR_SUCCESS) {
102 - srs_error("ffmpeg start failed. ret=%d", ret); 102 + srs_error("transcode ffmpeg start failed. ret=%d", ret);
103 return ret; 103 return ret;
104 } 104 }
105 105
106 // check ffmpeg status. 106 // check ffmpeg status.
107 if ((ret = ffmpeg->cycle()) != ERROR_SUCCESS) { 107 if ((ret = ffmpeg->cycle()) != ERROR_SUCCESS) {
108 - srs_error("ffmpeg cycle failed. ret=%d", ret); 108 + srs_error("transcode ffmpeg cycle failed. ret=%d", ret);
109 return ret; 109 return ret;
110 } 110 }
111 } 111 }
@@ -73,6 +73,11 @@ SrsFFMPEG::~SrsFFMPEG() @@ -73,6 +73,11 @@ SrsFFMPEG::~SrsFFMPEG()
73 stop(); 73 stop();
74 } 74 }
75 75
  76 +void SrsFFMPEG::set_iparams(string iparams)
  77 +{
  78 + _iparams = iparams;
  79 +}
  80 +
76 string SrsFFMPEG::output() 81 string SrsFFMPEG::output()
77 { 82 {
78 return _output; 83 return _output;
@@ -232,6 +237,11 @@ int SrsFFMPEG::start() @@ -232,6 +237,11 @@ int SrsFFMPEG::start()
232 // the filename associated with the file being executed. 237 // the filename associated with the file being executed.
233 params.push_back(ffmpeg); 238 params.push_back(ffmpeg);
234 239
  240 + // input params
  241 + if (!_iparams.empty()) {
  242 + params.push_back(_iparams);
  243 + }
  244 +
235 // input. 245 // input.
236 params.push_back("-f"); 246 params.push_back("-f");
237 params.push_back("flv"); 247 params.push_back("flv");
@@ -51,6 +51,7 @@ private: @@ -51,6 +51,7 @@ private:
51 int log_fd; 51 int log_fd;
52 private: 52 private:
53 std::string ffmpeg; 53 std::string ffmpeg;
  54 + std::string _iparams;
54 std::vector<std::string> vfilter; 55 std::vector<std::string> vfilter;
55 std::string vcodec; 56 std::string vcodec;
56 int vbitrate; 57 int vbitrate;
@@ -72,6 +73,7 @@ public: @@ -72,6 +73,7 @@ public:
72 SrsFFMPEG(std::string ffmpeg_bin); 73 SrsFFMPEG(std::string ffmpeg_bin);
73 virtual ~SrsFFMPEG(); 74 virtual ~SrsFFMPEG();
74 public: 75 public:
  76 + virtual void set_iparams(std::string iparams);
75 virtual std::string output(); 77 virtual std::string output();
76 public: 78 public:
77 virtual int initialize(std::string in, std::string out, std::string log); 79 virtual int initialize(std::string in, std::string out, std::string log);
@@ -29,6 +29,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -29,6 +29,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 #include <srs_app_config.hpp> 29 #include <srs_app_config.hpp>
30 #include <srs_kernel_log.hpp> 30 #include <srs_kernel_log.hpp>
31 #include <srs_app_ffmpeg.hpp> 31 #include <srs_app_ffmpeg.hpp>
  32 +#include <srs_app_pithy_print.hpp>
32 33
33 // when error, ingester sleep for a while and retry. 34 // when error, ingester sleep for a while and retry.
34 #define SRS_INGESTER_SLEEP_US (int64_t)(3*1000*1000LL) 35 #define SRS_INGESTER_SLEEP_US (int64_t)(3*1000*1000LL)
@@ -37,6 +38,7 @@ SrsIngester::SrsIngester() @@ -37,6 +38,7 @@ SrsIngester::SrsIngester()
37 { 38 {
38 // TODO: FIXME: support reload. 39 // TODO: FIXME: support reload.
39 pthread = new SrsThread(this, SRS_INGESTER_SLEEP_US); 40 pthread = new SrsThread(this, SRS_INGESTER_SLEEP_US);
  41 + pithy_print = new SrsPithyPrint(SRS_STAGE_INGESTER);
40 } 42 }
41 43
42 SrsIngester::~SrsIngester() 44 SrsIngester::~SrsIngester()
@@ -55,6 +57,17 @@ int SrsIngester::start() @@ -55,6 +57,17 @@ int SrsIngester::start()
55 return ret; 57 return ret;
56 } 58 }
57 59
  60 + // return for error or no engine.
  61 + if (ffmpegs.empty()) {
  62 + return ret;
  63 + }
  64 +
  65 + // start thread to run all encoding engines.
  66 + if ((ret = pthread->start()) != ERROR_SUCCESS) {
  67 + srs_error("st_thread_create failed. ret=%d", ret);
  68 + return ret;
  69 + }
  70 +
58 return ret; 71 return ret;
59 } 72 }
60 73
@@ -96,7 +109,7 @@ int SrsIngester::parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest @@ -96,7 +109,7 @@ int SrsIngester::parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest
96 _srs_config->get_transcode_engines(ingest, engines); 109 _srs_config->get_transcode_engines(ingest, engines);
97 if (engines.empty()) { 110 if (engines.empty()) {
98 SrsFFMPEG* ffmpeg = new SrsFFMPEG(ffmpeg_bin); 111 SrsFFMPEG* ffmpeg = new SrsFFMPEG(ffmpeg_bin);
99 - if ((ret = initialize_ffmpeg(ffmpeg, ingest, NULL)) != ERROR_SUCCESS) { 112 + if ((ret = initialize_ffmpeg(ffmpeg, vhost, ingest, NULL)) != ERROR_SUCCESS) {
100 srs_freep(ffmpeg); 113 srs_freep(ffmpeg);
101 if (ret != ERROR_ENCODER_LOOP) { 114 if (ret != ERROR_ENCODER_LOOP) {
102 srs_error("invalid ingest engine. ret=%d", ret); 115 srs_error("invalid ingest engine. ret=%d", ret);
@@ -112,7 +125,7 @@ int SrsIngester::parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest @@ -112,7 +125,7 @@ int SrsIngester::parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest
112 for (int i = 0; i < (int)engines.size(); i++) { 125 for (int i = 0; i < (int)engines.size(); i++) {
113 SrsConfDirective* engine = engines[i]; 126 SrsConfDirective* engine = engines[i];
114 SrsFFMPEG* ffmpeg = new SrsFFMPEG(ffmpeg_bin); 127 SrsFFMPEG* ffmpeg = new SrsFFMPEG(ffmpeg_bin);
115 - if ((ret = initialize_ffmpeg(ffmpeg, ingest, engine)) != ERROR_SUCCESS) { 128 + if ((ret = initialize_ffmpeg(ffmpeg, vhost, ingest, engine)) != ERROR_SUCCESS) {
116 srs_freep(ffmpeg); 129 srs_freep(ffmpeg);
117 if (ret != ERROR_ENCODER_LOOP) { 130 if (ret != ERROR_ENCODER_LOOP) {
118 srs_error("invalid ingest engine: %s %s", ingest->arg0().c_str(), engine->arg0().c_str()); 131 srs_error("invalid ingest engine: %s %s", ingest->arg0().c_str(), engine->arg0().c_str());
@@ -128,11 +141,35 @@ int SrsIngester::parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest @@ -128,11 +141,35 @@ int SrsIngester::parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest
128 141
129 void SrsIngester::stop() 142 void SrsIngester::stop()
130 { 143 {
  144 + pthread->stop();
  145 + clear_engines();
131 } 146 }
132 147
133 int SrsIngester::cycle() 148 int SrsIngester::cycle()
134 { 149 {
135 int ret = ERROR_SUCCESS; 150 int ret = ERROR_SUCCESS;
  151 +
  152 + std::vector<SrsFFMPEG*>::iterator it;
  153 + for (it = ffmpegs.begin(); it != ffmpegs.end(); ++it) {
  154 + SrsFFMPEG* ffmpeg = *it;
  155 +
  156 + // start all ffmpegs.
  157 + if ((ret = ffmpeg->start()) != ERROR_SUCCESS) {
  158 + srs_error("ingest ffmpeg start failed. ret=%d", ret);
  159 + return ret;
  160 + }
  161 +
  162 + // check ffmpeg status.
  163 + if ((ret = ffmpeg->cycle()) != ERROR_SUCCESS) {
  164 + srs_error("ingest ffmpeg cycle failed. ret=%d", ret);
  165 + return ret;
  166 + }
  167 + }
  168 +
  169 + // pithy print
  170 + ingester();
  171 + pithy_print->elapse(SRS_INGESTER_SLEEP_US / 1000);
  172 +
136 return ret; 173 return ret;
137 } 174 }
138 175
@@ -170,21 +207,109 @@ int SrsIngester::parse() @@ -170,21 +207,109 @@ int SrsIngester::parse()
170 return ret; 207 return ret;
171 } 208 }
172 209
173 -int SrsIngester::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective* ingest, SrsConfDirective* engine) 210 +int SrsIngester::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective* vhost, SrsConfDirective* ingest, SrsConfDirective* engine)
174 { 211 {
175 int ret = ERROR_SUCCESS; 212 int ret = ERROR_SUCCESS;
176 213
177 - std::string input = _srs_config->get_ingest_input(ingest);  
178 - if (input.empty()) { 214 + SrsConfDirective* listen = _srs_config->get_listen();
  215 + srs_assert(listen->args.size() > 0);
  216 + std::string port = listen->arg0();
  217 +
  218 + std::string output = _srs_config->get_engine_output(engine);
  219 + // output stream, to other/self server
  220 + // ie. rtmp://127.0.0.1:1935/live/livestream_sd
  221 + output = srs_string_replace(output, "[vhost]", vhost->arg0());
  222 + output = srs_string_replace(output, "[port]", port);
  223 + if (output.empty()) {
  224 + ret = ERROR_ENCODER_NO_OUTPUT;
  225 + srs_trace("empty ingest output url. ret=%d", ret);
  226 + return ret;
  227 + }
  228 +
  229 + // find the app and stream in rtmp url
  230 + std::string url = output;
  231 + std::string app, stream;
  232 + size_t pos = std::string::npos;
  233 + if ((pos = url.rfind("/")) != std::string::npos) {
  234 + stream = url.substr(pos + 1);
  235 + url = url.substr(0, pos);
  236 + }
  237 + if ((pos = url.rfind("/")) != std::string::npos) {
  238 + app = url.substr(pos + 1);
  239 + url = url.substr(0, pos);
  240 + }
  241 + if ((pos = app.rfind("?")) != std::string::npos) {
  242 + app = app.substr(0, pos);
  243 + }
  244 +
  245 + std::string log_file;
  246 + // write ffmpeg info to log file.
  247 + log_file = _srs_config->get_ffmpeg_log_dir();
  248 + log_file += "/";
  249 + log_file += "ingest";
  250 + log_file += "-";
  251 + log_file += vhost->arg0();
  252 + log_file += "-";
  253 + log_file += app;
  254 + log_file += "-";
  255 + log_file += stream;
  256 + log_file += ".log";
  257 +
  258 + // stream name: vhost/app/stream for print
  259 + input_stream_name = vhost->arg0();
  260 + input_stream_name += "/";
  261 + input_stream_name += app;
  262 + input_stream_name += "/";
  263 + input_stream_name += stream;
  264 +
  265 + // input
  266 + std::string input_type = _srs_config->get_ingest_input_type(ingest);
  267 + if (input_type.empty()) {
179 ret = ERROR_ENCODER_NO_INPUT; 268 ret = ERROR_ENCODER_NO_INPUT;
180 - srs_trace("empty ingest intput. ret=%d", ret); 269 + srs_trace("empty ingest intput type. ret=%d", ret);
  270 + return ret;
  271 + }
  272 +
  273 + if (input_type == SRS_INGEST_TYPE_FILE) {
  274 + std::string input_url = _srs_config->get_ingest_input_url(ingest);
  275 + if (input_url.empty()) {
  276 + ret = ERROR_ENCODER_NO_INPUT;
  277 + srs_trace("empty ingest intput url. ret=%d", ret);
  278 + return ret;
  279 + }
  280 +
  281 + // for file, set re.
  282 + ffmpeg->set_iparams("-re");
  283 +
  284 + if ((ret = ffmpeg->initialize(input_url, output, log_file)) != ERROR_SUCCESS) {
181 return ret; 285 return ret;
182 } 286 }
  287 + } else {
  288 + ret = ERROR_ENCODER_INPUT_TYPE;
  289 + srs_error("invalid ingest type=%s, ret=%d", input_type.c_str(), ret);
  290 + }
183 291
184 if (!engine || !_srs_config->get_engine_enabled(engine)) { 292 if (!engine || !_srs_config->get_engine_enabled(engine)) {
  293 + if ((ret = ffmpeg->initialize_copy()) != ERROR_SUCCESS) {
  294 + return ret;
  295 + }
  296 + } else {
  297 + if ((ret = ffmpeg->initialize_transcode(engine)) != ERROR_SUCCESS) {
  298 + return ret;
  299 + }
185 } 300 }
186 301
187 return ret; 302 return ret;
188 } 303 }
189 304
  305 +void SrsIngester::ingester()
  306 +{
  307 + // reportable
  308 + if (pithy_print->can_print()) {
  309 + // TODO: FIXME: show more info.
  310 + srs_trace("-> time=%"PRId64", ingesters=%d, input=%s",
  311 + pithy_print->get_age(), (int)ffmpegs.size(), input_stream_name.c_str());
  312 + }
  313 +}
  314 +
190 #endif 315 #endif
@@ -37,6 +37,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -37,6 +37,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 37
38 class SrsFFMPEG; 38 class SrsFFMPEG;
39 class SrsConfDirective; 39 class SrsConfDirective;
  40 +class SrsPithyPrint;
40 41
41 /** 42 /**
42 * ingest file/stream/device, 43 * ingest file/stream/device,
@@ -46,9 +47,11 @@ class SrsConfDirective; @@ -46,9 +47,11 @@ class SrsConfDirective;
46 class SrsIngester : public ISrsThreadHandler 47 class SrsIngester : public ISrsThreadHandler
47 { 48 {
48 private: 49 private:
  50 + std::string input_stream_name;
49 std::vector<SrsFFMPEG*> ffmpegs; 51 std::vector<SrsFFMPEG*> ffmpegs;
50 private: 52 private:
51 SrsThread* pthread; 53 SrsThread* pthread;
  54 + SrsPithyPrint* pithy_print;
52 public: 55 public:
53 SrsIngester(); 56 SrsIngester();
54 virtual ~SrsIngester(); 57 virtual ~SrsIngester();
@@ -64,7 +67,8 @@ private: @@ -64,7 +67,8 @@ private:
64 virtual int parse(); 67 virtual int parse();
65 virtual int parse_ingesters(SrsConfDirective* vhost); 68 virtual int parse_ingesters(SrsConfDirective* vhost);
66 virtual int parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest); 69 virtual int parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest);
67 - virtual int initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective* ingest, SrsConfDirective* engine); 70 + virtual int initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective* vhost, SrsConfDirective* ingest, SrsConfDirective* engine);
  71 + virtual void ingester();
68 }; 72 };
69 73
70 #endif 74 #endif
@@ -71,6 +71,10 @@ struct SrsStageInfo : public ISrsReloadHandler @@ -71,6 +71,10 @@ struct SrsStageInfo : public ISrsReloadHandler
71 pithy_print_time_ms = _srs_config->get_pithy_print_encoder(); 71 pithy_print_time_ms = _srs_config->get_pithy_print_encoder();
72 break; 72 break;
73 } 73 }
  74 + case SRS_STAGE_INGESTER: {
  75 + pithy_print_time_ms = _srs_config->get_pithy_print_ingester();
  76 + break;
  77 + }
74 case SRS_STAGE_HLS: { 78 case SRS_STAGE_HLS: {
75 pithy_print_time_ms = _srs_config->get_pithy_print_hls(); 79 pithy_print_time_ms = _srs_config->get_pithy_print_hls();
76 break; 80 break;
@@ -108,7 +112,8 @@ int SrsPithyPrint::enter_stage() @@ -108,7 +112,8 @@ int SrsPithyPrint::enter_stage()
108 112
109 std::map<int, SrsStageInfo*>::iterator it = _srs_stages.find(stage_id); 113 std::map<int, SrsStageInfo*>::iterator it = _srs_stages.find(stage_id);
110 if (it == _srs_stages.end()) { 114 if (it == _srs_stages.end()) {
111 - stage = _srs_stages[stage_id] = new SrsStageInfo(stage_id); 115 + stage = new SrsStageInfo(stage_id);
  116 + _srs_stages[stage_id] = stage;
112 } else { 117 } else {
113 stage = it->second; 118 stage = it->second;
114 } 119 }
@@ -40,6 +40,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -40,6 +40,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40 #define SRS_STAGE_ENCODER 4 40 #define SRS_STAGE_ENCODER 4
41 // the pithy stage for all hls. 41 // the pithy stage for all hls.
42 #define SRS_STAGE_HLS 5 42 #define SRS_STAGE_HLS 5
  43 +// the pithy stage for all ingesters.
  44 +#define SRS_STAGE_INGESTER 6
43 45
44 /** 46 /**
45 * the stage is used for a collection of object to do print, 47 * the stage is used for a collection of object to do print,
@@ -164,13 +164,13 @@ SrsServer::SrsServer() @@ -164,13 +164,13 @@ SrsServer::SrsServer()
164 _srs_config->subscribe(this); 164 _srs_config->subscribe(this);
165 165
166 #ifdef SRS_HTTP_API 166 #ifdef SRS_HTTP_API
167 - http_api_handler = SrsHttpHandler::create_http_api(); 167 + http_api_handler = NULL;
168 #endif 168 #endif
169 #ifdef SRS_HTTP_SERVER 169 #ifdef SRS_HTTP_SERVER
170 - http_stream_handler = SrsHttpHandler::create_http_stream(); 170 + http_stream_handler = NULL;
171 #endif 171 #endif
172 #ifdef SRS_INGEST 172 #ifdef SRS_INGEST
173 - ingester = new SrsIngester(); 173 + ingester = NULL;
174 #endif 174 #endif
175 } 175 }
176 176
@@ -206,6 +206,19 @@ int SrsServer::initialize() @@ -206,6 +206,19 @@ int SrsServer::initialize()
206 int ret = ERROR_SUCCESS; 206 int ret = ERROR_SUCCESS;
207 207
208 #ifdef SRS_HTTP_API 208 #ifdef SRS_HTTP_API
  209 + srs_assert(!http_api_handler);
  210 + http_api_handler = SrsHttpHandler::create_http_api();
  211 +#endif
  212 +#ifdef SRS_HTTP_SERVER
  213 + srs_assert(!http_stream_handler);
  214 + http_stream_handler = SrsHttpHandler::create_http_stream();
  215 +#endif
  216 +#ifdef SRS_INGEST
  217 + srs_assert(!ingester);
  218 + ingester = new SrsIngester();
  219 +#endif
  220 +
  221 +#ifdef SRS_HTTP_API
209 if ((ret = http_api_handler->initialize()) != ERROR_SUCCESS) { 222 if ((ret = http_api_handler->initialize()) != ERROR_SUCCESS) {
210 return ret; 223 return ret;
211 } 224 }
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 // current release version 31 // current release version
32 #define VERSION_MAJOR "0" 32 #define VERSION_MAJOR "0"
33 #define VERSION_MINOR "9" 33 #define VERSION_MINOR "9"
34 -#define VERSION_REVISION "52" 34 +#define VERSION_REVISION "53"
35 #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION 35 #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION
36 // server info. 36 // server info.
37 #define RTMP_SIG_SRS_KEY "srs" 37 #define RTMP_SIG_SRS_KEY "srs"
@@ -155,6 +155,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -155,6 +155,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
155 #define ERROR_ENCODER_DUP2 716 155 #define ERROR_ENCODER_DUP2 716
156 #define ERROR_ENCODER_PARSE 717 156 #define ERROR_ENCODER_PARSE 717
157 #define ERROR_ENCODER_NO_INPUT 718 157 #define ERROR_ENCODER_NO_INPUT 718
  158 +#define ERROR_ENCODER_NO_OUTPUT 719
  159 +#define ERROR_ENCODER_INPUT_TYPE 720
158 160
159 #define ERROR_HTTP_PARSE_URI 800 161 #define ERROR_HTTP_PARSE_URI 800
160 #define ERROR_HTTP_DATA_INVLIAD 801 162 #define ERROR_HTTP_DATA_INVLIAD 801