diff --git a/trunk/src/core/srs_core_client.cpp b/trunk/src/core/srs_core_client.cpp index ee10425c1..ec16b95fc 100644 --- a/trunk/src/core/srs_core_client.cpp +++ b/trunk/src/core/srs_core_client.cpp @@ -41,6 +41,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define SRS_PULSE_TIMEOUT_MS 100 #define SRS_SEND_TIMEOUT_MS 5000000L #define SRS_RECV_TIMEOUT_MS SRS_SEND_TIMEOUT_MS +#define SRS_STREAM_BUSY_SLEEP_MS 2000 SrsClient::SrsClient(SrsServer* srs_server, st_netfd_t client_stfd) : SrsConnection(srs_server, client_stfd) @@ -152,6 +153,16 @@ int SrsClient::do_cycle() SrsSource* source = SrsSource::find(req->get_stream_url()); srs_assert(source != NULL); + // check publish available. + if (type != SrsClientPlay && !source->can_publish()) { + ret = ERROR_SYSTEM_STREAM_BUSY; + srs_warn("stream %s is already publishing. ret=%d", + req->get_stream_url().c_str(), ret); + // to delay request + st_usleep(SRS_STREAM_BUSY_SLEEP_MS * 1000); + return ret; + } + bool enabled_cache = true; conf = config->get_gop_cache(req->vhost); if (conf && conf->arg0() == "off") { diff --git a/trunk/src/core/srs_core_error.hpp b/trunk/src/core/srs_core_error.hpp index dc421a64d..ed1bef447 100644 --- a/trunk/src/core/srs_core_error.hpp +++ b/trunk/src/core/srs_core_error.hpp @@ -78,6 +78,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define ERROR_SYSTEM_CONFIG_BLOCK_START 407 #define ERROR_SYSTEM_CONFIG_BLOCK_END 408 #define ERROR_SYSTEM_CONFIG_EOF 409 +#define ERROR_SYSTEM_STREAM_BUSY 410 // see librtmp. // failed when open ssl create the dh diff --git a/trunk/src/core/srs_core_source.cpp b/trunk/src/core/srs_core_source.cpp index c731aac80..e5d61ec76 100644 --- a/trunk/src/core/srs_core_source.cpp +++ b/trunk/src/core/srs_core_source.cpp @@ -268,6 +268,7 @@ SrsSource::SrsSource(std::string _stream_url) enable_gop_cache = true; video_frame_rate = audio_sample_rate = 0; + _can_publish = true; } SrsSource::~SrsSource() @@ -290,6 +291,11 @@ SrsSource::~SrsSource() #endif } +bool SrsSource::can_publish() +{ + return _can_publish; +} + int SrsSource::on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata) { int ret = ERROR_SUCCESS; @@ -465,11 +471,13 @@ int SrsSource::on_video(SrsCommonMessage* video) #ifdef SRS_HLS int SrsSource::on_publish(std::string vhost, std::string app, std::string stream) { + _can_publish = false; return hls->on_publish(vhost, app, stream); } #else int SrsSource::on_publish(std::string /*vhost*/, std::string /*app*/, std::string /*stream*/) { + _can_publish = false; return ERROR_SUCCESS; } #endif @@ -489,6 +497,8 @@ void SrsSource::on_unpublish() srs_freep(cache_sh_audio); srs_trace("clear cache/metadata/sequence-headers when unpublish."); + + _can_publish = true; } int SrsSource::create_consumer(SrsConsumer*& consumer) diff --git a/trunk/src/core/srs_core_source.hpp b/trunk/src/core/srs_core_source.hpp index 0d6a221eb..2ed1e3fa6 100644 --- a/trunk/src/core/srs_core_source.hpp +++ b/trunk/src/core/srs_core_source.hpp @@ -157,6 +157,10 @@ private: * the video frame rate in metadata. */ int video_frame_rate; + /** + * can publish, true when is not streaming + */ + bool _can_publish; private: SrsSharedPtrMessage* cache_metadata; // the cached video sequence header. @@ -167,6 +171,7 @@ public: SrsSource(std::string _stream_url); virtual ~SrsSource(); public: + virtual bool can_publish(); virtual int on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata); virtual int on_audio(SrsCommonMessage* audio); virtual int on_video(SrsCommonMessage* video);