winlin

reap the transcode process

@@ -72,18 +72,19 @@ vhost __defaultVhost__ { @@ -72,18 +72,19 @@ vhost __defaultVhost__ {
72 vhost dev { 72 vhost dev {
73 enabled on; 73 enabled on;
74 gop_cache on; 74 gop_cache on;
75 - hls on; 75 + hls off;
76 hls_path ./objs/nginx/html; 76 hls_path ./objs/nginx/html;
77 hls_fragment 5; 77 hls_fragment 5;
78 hls_window 30; 78 hls_window 30;
79 #forward 127.0.0.1:19350; 79 #forward 127.0.0.1:19350;
80 - forward 127.0.0.1:1936; 80 + #forward 127.0.0.1:1936;
81 transcode { 81 transcode {
82 - enabled off; 82 + enabled on;
83 ffmpeg ./objs/ffmpeg/bin/ffmpeg; 83 ffmpeg ./objs/ffmpeg/bin/ffmpeg;
84 engine dev { 84 engine dev {
85 enabled on; 85 enabled on;
86 vfilter { 86 vfilter {
  87 + t 10;
87 } 88 }
88 vcodec libx264; 89 vcodec libx264;
89 vbitrate 300; 90 vbitrate 300;
@@ -25,6 +25,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -25,6 +25,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 25
26 #include <stdlib.h> 26 #include <stdlib.h>
27 #include <unistd.h> 27 #include <unistd.h>
  28 +#include <sys/wait.h>
28 29
29 #include <algorithm> 30 #include <algorithm>
30 31
@@ -356,6 +357,34 @@ int SrsFFMPEG::start() @@ -356,6 +357,34 @@ int SrsFFMPEG::start()
356 return ret; 357 return ret;
357 } 358 }
358 359
  360 +int SrsFFMPEG::cycle()
  361 +{
  362 + int ret = ERROR_SUCCESS;
  363 +
  364 + if (!started) {
  365 + return ret;
  366 + }
  367 +
  368 + int status = 0;
  369 + pid_t p = waitpid(pid, &status, WNOHANG);
  370 +
  371 + if (p < 0) {
  372 + ret = ERROR_SYSTEM_WAITPID;
  373 + srs_error("transcode waitpid failed, pid=%d, ret=%d", pid, ret);
  374 + return ret;
  375 + }
  376 +
  377 + if (p == 0) {
  378 + srs_info("transcode process pid=%d is running.", pid);
  379 + return ret;
  380 + }
  381 +
  382 + srs_trace("transcode process pid=%d terminate, restart it.", pid);
  383 + started = false;
  384 +
  385 + return ret;
  386 +}
  387 +
359 void SrsFFMPEG::stop() 388 void SrsFFMPEG::stop()
360 { 389 {
361 if (!started) { 390 if (!started) {
@@ -538,17 +567,22 @@ int SrsEncoder::cycle() @@ -538,17 +567,22 @@ int SrsEncoder::cycle()
538 { 567 {
539 int ret = ERROR_SUCCESS; 568 int ret = ERROR_SUCCESS;
540 569
541 - // start all ffmpegs.  
542 std::vector<SrsFFMPEG*>::iterator it; 570 std::vector<SrsFFMPEG*>::iterator it;
543 for (it = ffmpegs.begin(); it != ffmpegs.end(); ++it) { 571 for (it = ffmpegs.begin(); it != ffmpegs.end(); ++it) {
544 SrsFFMPEG* ffmpeg = *it; 572 SrsFFMPEG* ffmpeg = *it;
  573 +
  574 + // start all ffmpegs.
545 if ((ret = ffmpeg->start()) != ERROR_SUCCESS) { 575 if ((ret = ffmpeg->start()) != ERROR_SUCCESS) {
546 srs_error("ffmpeg start failed. ret=%d", ret); 576 srs_error("ffmpeg start failed. ret=%d", ret);
547 return ret; 577 return ret;
548 } 578 }
549 - }  
550 579
551 - // TODO: cycle all processes. 580 + // check ffmpeg status.
  581 + if ((ret = ffmpeg->cycle()) != ERROR_SUCCESS) {
  582 + srs_error("ffmpeg cycle failed. ret=%d", ret);
  583 + return ret;
  584 + }
  585 + }
552 586
553 return ret; 587 return ret;
554 } 588 }
@@ -73,6 +73,7 @@ public: @@ -73,6 +73,7 @@ public:
73 public: 73 public:
74 virtual int initialize(SrsRequest* req, SrsConfDirective* engine); 74 virtual int initialize(SrsRequest* req, SrsConfDirective* engine);
75 virtual int start(); 75 virtual int start();
  76 + virtual int cycle();
76 virtual void stop(); 77 virtual void stop();
77 }; 78 };
78 79
@@ -86,6 +86,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -86,6 +86,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
86 #define ERROR_SYSTEM_IP_INVALID 411 86 #define ERROR_SYSTEM_IP_INVALID 411
87 #define ERROR_SYSTEM_CONFIG_TOO_LARGE 412 87 #define ERROR_SYSTEM_CONFIG_TOO_LARGE 412
88 #define ERROR_SYSTEM_FORWARD_LOOP 413 88 #define ERROR_SYSTEM_FORWARD_LOOP 413
  89 +#define ERROR_SYSTEM_WAITPID 414
89 90
90 // see librtmp. 91 // see librtmp.
91 // failed when open ssl create the dh 92 // failed when open ssl create the dh
@@ -502,6 +502,7 @@ SrsM3u8Muxer::SrsM3u8Muxer() @@ -502,6 +502,7 @@ SrsM3u8Muxer::SrsM3u8Muxer()
502 video_stream_dts = 0; 502 video_stream_dts = 0;
503 file_index = 0; 503 file_index = 0;
504 current = NULL; 504 current = NULL;
  505 + _is_open = false;
505 } 506 }
506 507
507 SrsM3u8Muxer::~SrsM3u8Muxer() 508 SrsM3u8Muxer::~SrsM3u8Muxer()
@@ -516,6 +517,11 @@ SrsM3u8Muxer::~SrsM3u8Muxer() @@ -516,6 +517,11 @@ SrsM3u8Muxer::~SrsM3u8Muxer()
516 srs_freep(current); 517 srs_freep(current);
517 } 518 }
518 519
  520 +bool SrsM3u8Muxer::is_open()
  521 +{
  522 + return _is_open;
  523 +}
  524 +
519 int SrsM3u8Muxer::update_config( 525 int SrsM3u8Muxer::update_config(
520 std::string _app, std::string _stream, 526 std::string _app, std::string _stream,
521 std::string path, int fragment, int window 527 std::string path, int fragment, int window
@@ -571,6 +577,8 @@ int SrsM3u8Muxer::segment_open() @@ -571,6 +577,8 @@ int SrsM3u8Muxer::segment_open()
571 srs_info("open HLS muxer success. vhost=%s, path=%s", 577 srs_info("open HLS muxer success. vhost=%s, path=%s",
572 vhost.c_str(), current->full_path.c_str()); 578 vhost.c_str(), current->full_path.c_str());
573 579
  580 + _is_open = true;
  581 +
574 return ret; 582 return ret;
575 } 583 }
576 584
@@ -709,6 +717,8 @@ int SrsM3u8Muxer::segment_close() @@ -709,6 +717,8 @@ int SrsM3u8Muxer::segment_close()
709 return ret; 717 return ret;
710 } 718 }
711 719
  720 + _is_open = false;
  721 +
712 return ret; 722 return ret;
713 } 723 }
714 724
@@ -1171,12 +1181,14 @@ void SrsHls::on_unpublish() @@ -1171,12 +1181,14 @@ void SrsHls::on_unpublish()
1171 { 1181 {
1172 int ret = ERROR_SUCCESS; 1182 int ret = ERROR_SUCCESS;
1173 1183
  1184 + if (muxer->is_open()) {
1174 // close muxer when unpublish. 1185 // close muxer when unpublish.
1175 ret = ts_cache->flush_audio(muxer); 1186 ret = ts_cache->flush_audio(muxer);
1176 ret += muxer->segment_close(); 1187 ret += muxer->segment_close();
  1188 +
1177 if (ret != ERROR_SUCCESS) { 1189 if (ret != ERROR_SUCCESS) {
1178 srs_error("ignore m3u8 muxer flush/close audio failed. ret=%d", ret); 1190 srs_error("ignore m3u8 muxer flush/close audio failed. ret=%d", ret);
1179 - return; 1191 + }
1180 } 1192 }
1181 1193
1182 hls_enabled = false; 1194 hls_enabled = false;
@@ -131,6 +131,7 @@ private: @@ -131,6 +131,7 @@ private:
131 int hls_fragment; 131 int hls_fragment;
132 int hls_window; 132 int hls_window;
133 private: 133 private:
  134 + bool _is_open;
134 int file_index; 135 int file_index;
135 std::string m3u8; 136 std::string m3u8;
136 private: 137 private:
@@ -148,6 +149,7 @@ public: @@ -148,6 +149,7 @@ public:
148 SrsM3u8Muxer(); 149 SrsM3u8Muxer();
149 virtual ~SrsM3u8Muxer(); 150 virtual ~SrsM3u8Muxer();
150 public: 151 public:
  152 + virtual bool is_open();
151 virtual int update_config(std::string _app, std::string _stream, std::string path, int fragment, int window); 153 virtual int update_config(std::string _app, std::string _stream, std::string path, int fragment, int window);
152 virtual int segment_open(); 154 virtual int segment_open();
153 virtual int flush_audio(SrsMpegtsFrame* af, SrsCodecBuffer* ab); 155 virtual int flush_audio(SrsMpegtsFrame* af, SrsCodecBuffer* ab);