diff --git a/trunk/conf/srs.conf b/trunk/conf/srs.conf index 6d2c91400..8d3276674 100755 --- a/trunk/conf/srs.conf +++ b/trunk/conf/srs.conf @@ -72,18 +72,19 @@ vhost __defaultVhost__ { vhost dev { enabled on; gop_cache on; - hls on; + hls off; hls_path ./objs/nginx/html; hls_fragment 5; hls_window 30; #forward 127.0.0.1:19350; - forward 127.0.0.1:1936; + #forward 127.0.0.1:1936; transcode { - enabled off; + enabled on; ffmpeg ./objs/ffmpeg/bin/ffmpeg; engine dev { enabled on; vfilter { + t 10; } vcodec libx264; vbitrate 300; diff --git a/trunk/src/core/srs_core_encoder.cpp b/trunk/src/core/srs_core_encoder.cpp index c42763e5e..97aac00d1 100644 --- a/trunk/src/core/srs_core_encoder.cpp +++ b/trunk/src/core/srs_core_encoder.cpp @@ -25,6 +25,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include #include @@ -356,6 +357,34 @@ int SrsFFMPEG::start() return ret; } +int SrsFFMPEG::cycle() +{ + int ret = ERROR_SUCCESS; + + if (!started) { + return ret; + } + + int status = 0; + pid_t p = waitpid(pid, &status, WNOHANG); + + if (p < 0) { + ret = ERROR_SYSTEM_WAITPID; + srs_error("transcode waitpid failed, pid=%d, ret=%d", pid, ret); + return ret; + } + + if (p == 0) { + srs_info("transcode process pid=%d is running.", pid); + return ret; + } + + srs_trace("transcode process pid=%d terminate, restart it.", pid); + started = false; + + return ret; +} + void SrsFFMPEG::stop() { if (!started) { @@ -538,18 +567,23 @@ int SrsEncoder::cycle() { int ret = ERROR_SUCCESS; - // start all ffmpegs. std::vector::iterator it; for (it = ffmpegs.begin(); it != ffmpegs.end(); ++it) { SrsFFMPEG* ffmpeg = *it; + + // start all ffmpegs. if ((ret = ffmpeg->start()) != ERROR_SUCCESS) { srs_error("ffmpeg start failed. ret=%d", ret); return ret; } + + // check ffmpeg status. + if ((ret = ffmpeg->cycle()) != ERROR_SUCCESS) { + srs_error("ffmpeg cycle failed. ret=%d", ret); + return ret; + } } - // TODO: cycle all processes. - return ret; } diff --git a/trunk/src/core/srs_core_encoder.hpp b/trunk/src/core/srs_core_encoder.hpp index 5a8ad9eb2..73c345ae1 100644 --- a/trunk/src/core/srs_core_encoder.hpp +++ b/trunk/src/core/srs_core_encoder.hpp @@ -73,6 +73,7 @@ public: public: virtual int initialize(SrsRequest* req, SrsConfDirective* engine); virtual int start(); + virtual int cycle(); virtual void stop(); }; diff --git a/trunk/src/core/srs_core_error.hpp b/trunk/src/core/srs_core_error.hpp index eea5f56ad..ddfeb053a 100644 --- a/trunk/src/core/srs_core_error.hpp +++ b/trunk/src/core/srs_core_error.hpp @@ -86,6 +86,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define ERROR_SYSTEM_IP_INVALID 411 #define ERROR_SYSTEM_CONFIG_TOO_LARGE 412 #define ERROR_SYSTEM_FORWARD_LOOP 413 +#define ERROR_SYSTEM_WAITPID 414 // see librtmp. // failed when open ssl create the dh diff --git a/trunk/src/core/srs_core_hls.cpp b/trunk/src/core/srs_core_hls.cpp index 1cca34985..6f0f3ec12 100644 --- a/trunk/src/core/srs_core_hls.cpp +++ b/trunk/src/core/srs_core_hls.cpp @@ -502,6 +502,7 @@ SrsM3u8Muxer::SrsM3u8Muxer() video_stream_dts = 0; file_index = 0; current = NULL; + _is_open = false; } SrsM3u8Muxer::~SrsM3u8Muxer() @@ -516,6 +517,11 @@ SrsM3u8Muxer::~SrsM3u8Muxer() srs_freep(current); } +bool SrsM3u8Muxer::is_open() +{ + return _is_open; +} + int SrsM3u8Muxer::update_config( std::string _app, std::string _stream, std::string path, int fragment, int window @@ -571,6 +577,8 @@ int SrsM3u8Muxer::segment_open() srs_info("open HLS muxer success. vhost=%s, path=%s", vhost.c_str(), current->full_path.c_str()); + _is_open = true; + return ret; } @@ -709,6 +717,8 @@ int SrsM3u8Muxer::segment_close() return ret; } + _is_open = false; + return ret; } @@ -1171,12 +1181,14 @@ void SrsHls::on_unpublish() { int ret = ERROR_SUCCESS; - // close muxer when unpublish. - ret = ts_cache->flush_audio(muxer); - ret += muxer->segment_close(); - if (ret != ERROR_SUCCESS) { - srs_error("ignore m3u8 muxer flush/close audio failed. ret=%d", ret); - return; + if (muxer->is_open()) { + // close muxer when unpublish. + ret = ts_cache->flush_audio(muxer); + ret += muxer->segment_close(); + + if (ret != ERROR_SUCCESS) { + srs_error("ignore m3u8 muxer flush/close audio failed. ret=%d", ret); + } } hls_enabled = false; diff --git a/trunk/src/core/srs_core_hls.hpp b/trunk/src/core/srs_core_hls.hpp index 0a8aa79d6..8b326ac7d 100644 --- a/trunk/src/core/srs_core_hls.hpp +++ b/trunk/src/core/srs_core_hls.hpp @@ -131,6 +131,7 @@ private: int hls_fragment; int hls_window; private: + bool _is_open; int file_index; std::string m3u8; private: @@ -148,6 +149,7 @@ public: SrsM3u8Muxer(); virtual ~SrsM3u8Muxer(); public: + virtual bool is_open(); virtual int update_config(std::string _app, std::string _stream, std::string path, int fragment, int window); virtual int segment_open(); virtual int flush_audio(SrsMpegtsFrame* af, SrsCodecBuffer* ab);