1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-13 20:01:56 +00:00

RTC: Refine source state to created and delivering

This commit is contained in:
winlin 2020-08-17 18:15:34 +08:00
parent 5afabe4adf
commit 66a0143f14
5 changed files with 42 additions and 19 deletions

View file

@ -1538,6 +1538,7 @@ srs_error_t SrsRtcConnection::add_publisher(SrsRequest* req, const SrsSdp& remot
SrsRtcStreamDescription* stream_desc = new SrsRtcStreamDescription(); SrsRtcStreamDescription* stream_desc = new SrsRtcStreamDescription();
SrsAutoFree(SrsRtcStreamDescription, stream_desc); SrsAutoFree(SrsRtcStreamDescription, stream_desc);
if ((err = negotiate_publish_capability(req, remote_sdp, stream_desc)) != srs_success) { if ((err = negotiate_publish_capability(req, remote_sdp, stream_desc)) != srs_success) {
return srs_error_wrap(err, "publish negotiate"); return srs_error_wrap(err, "publish negotiate");
} }
@ -1551,8 +1552,16 @@ srs_error_t SrsRtcConnection::add_publisher(SrsRequest* req, const SrsSdp& remot
return srs_error_wrap(err, "create source"); return srs_error_wrap(err, "create source");
} }
// When SDP is done, we set the stream to create state, to prevent multiple publisher.
if (!source->can_publish()) {
return srs_error_new(ERROR_RTC_SOURCE_BUSY, "stream %s busy", req->get_stream_url().c_str());
}
source->set_stream_created();
// Apply the SDP to source.
source->set_stream_desc(stream_desc->copy()); source->set_stream_desc(stream_desc->copy());
// TODO: FIXME: What happends when error?
if ((err = create_publisher(req, stream_desc)) != srs_success) { if ((err = create_publisher(req, stream_desc)) != srs_success) {
return srs_error_wrap(err, "create publish"); return srs_error_wrap(err, "create publish");
} }
@ -3060,9 +3069,7 @@ srs_error_t SrsRtcConnection::create_publisher(SrsRequest* req, SrsRtcStreamDesc
{ {
srs_error_t err = srs_success; srs_error_t err = srs_success;
if (!stream_desc) { srs_assert(stream_desc);
return srs_error_new(ERROR_RTC_STREAM_DESC, "rtc publisher init");
}
// Ignore if exists. // Ignore if exists.
if(publishers_.end() != publishers_.find(req->get_stream_url())) { if(publishers_.end() != publishers_.find(req->get_stream_url())) {

View file

@ -417,7 +417,6 @@ srs_error_t SrsRtcServer::create_session(
return srs_error_wrap(err, "create source"); return srs_error_wrap(err, "create source");
} }
// TODO: FIXME: Refine the API for stream status manage.
if (publish && !source->can_publish()) { if (publish && !source->can_publish()) {
return srs_error_new(ERROR_RTC_SOURCE_BUSY, "stream %s busy", req->get_stream_url().c_str()); return srs_error_new(ERROR_RTC_SOURCE_BUSY, "stream %s busy", req->get_stream_url().c_str());
} }

View file

@ -290,7 +290,9 @@ ISrsRtcPublishStream::~ISrsRtcPublishStream()
SrsRtcStream::SrsRtcStream() SrsRtcStream::SrsRtcStream()
{ {
_can_publish = true; is_created_ = false;
is_delivering_packets_ = false;
publish_stream_ = NULL; publish_stream_ = NULL;
stream_desc_ = NULL; stream_desc_ = NULL;
@ -408,7 +410,13 @@ void SrsRtcStream::on_consumer_destroy(SrsRtcConsumer* consumer)
bool SrsRtcStream::can_publish() bool SrsRtcStream::can_publish()
{ {
return _can_publish; return !is_created_;
}
void SrsRtcStream::set_stream_created()
{
srs_assert(!is_created_ && !is_delivering_packets_);
is_created_ = true;
} }
srs_error_t SrsRtcStream::on_publish() srs_error_t SrsRtcStream::on_publish()
@ -418,7 +426,10 @@ srs_error_t SrsRtcStream::on_publish()
// update the request object. // update the request object.
srs_assert(req); srs_assert(req);
_can_publish = false; // For RTC, DTLS is done, and we are ready to deliver packets.
// @note For compatible with RTMP, we also set the is_created_, it MUST be created here.
is_created_ = true;
is_delivering_packets_ = true;
// whatever, the publish thread is the source or edge source, // whatever, the publish thread is the source or edge source,
// save its id to srouce id. // save its id to srouce id.
@ -434,13 +445,15 @@ srs_error_t SrsRtcStream::on_publish()
void SrsRtcStream::on_unpublish() void SrsRtcStream::on_unpublish()
{ {
// ignore when already unpublished. // ignore when already unpublished.
if (_can_publish) { if (!is_created_) {
return; return;
} }
srs_trace("cleanup when unpublish"); srs_trace("cleanup when unpublish, created=%u, deliver=%u", is_created_, is_delivering_packets_);
is_created_ = false;
is_delivering_packets_ = false;
_can_publish = true;
_source_id = SrsContextId(); _source_id = SrsContextId();
// TODO: FIXME: Handle by statistic. // TODO: FIXME: Handle by statistic.

View file

@ -152,8 +152,10 @@ private:
private: private:
// To delivery stream to clients. // To delivery stream to clients.
std::vector<SrsRtcConsumer*> consumers; std::vector<SrsRtcConsumer*> consumers;
// Whether source is avaiable for publishing. // Whether stream is created, that is, SDP is done.
bool _can_publish; bool is_created_;
// Whether stream is delivering data, that is, DTLS is done.
bool is_delivering_packets_;
public: public:
SrsRtcStream(); SrsRtcStream();
virtual ~SrsRtcStream(); virtual ~SrsRtcStream();
@ -179,7 +181,10 @@ public:
virtual srs_error_t consumer_dumps(SrsRtcConsumer* consumer, bool ds = true, bool dm = true, bool dg = true); virtual srs_error_t consumer_dumps(SrsRtcConsumer* consumer, bool ds = true, bool dm = true, bool dg = true);
virtual void on_consumer_destroy(SrsRtcConsumer* consumer); virtual void on_consumer_destroy(SrsRtcConsumer* consumer);
// Whether we can publish stream to the source, return false if it exists. // Whether we can publish stream to the source, return false if it exists.
// @remark Note that when SDP is done, we set the stream is not able to publish.
virtual bool can_publish(); virtual bool can_publish();
// For RTC, the stream is created when SDP is done, and then do DTLS
virtual void set_stream_created();
// When start publish stream. // When start publish stream.
virtual srs_error_t on_publish(); virtual srs_error_t on_publish();
// When stop publish stream. // When stop publish stream.

View file

@ -354,13 +354,12 @@
#define ERROR_RTC_INVALID_PARAMS 5023 #define ERROR_RTC_INVALID_PARAMS 5023
#define ERROR_RTC_DUMMY_BRIDGER 5024 #define ERROR_RTC_DUMMY_BRIDGER 5024
#define ERROR_RTC_STREM_STARTED 5025 #define ERROR_RTC_STREM_STARTED 5025
#define ERROR_RTC_STREAM_DESC 5026 #define ERROR_RTC_TRACK_CODEC 5026
#define ERROR_RTC_TRACK_CODEC 5027 #define ERROR_RTC_NO_PLAYER 5027
#define ERROR_RTC_NO_PLAYER 5028 #define ERROR_RTC_NO_PUBLISHER 5028
#define ERROR_RTC_NO_PUBLISHER 5029 #define ERROR_RTC_DUPLICATED_SSRC 5029
#define ERROR_RTC_DUPLICATED_SSRC 5030 #define ERROR_RTC_NO_TRACK 5030
#define ERROR_RTC_NO_TRACK 5031 #define ERROR_RTC_RTCP_EMPTY_RR 5031
#define ERROR_RTC_RTCP_EMPTY_RR 5032
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
// GB28181 API error. // GB28181 API error.