winlin

Fix #844, support Haivision encoder. 2.0.238

... ... @@ -336,6 +336,7 @@ Remark:
## History
* v2.0, 2017-04-15, Fix [#844][bug #844], support Haivision encoder. 2.0.238
* v2.0, 2017-04-15, Merge [#846][bug #846], fix fd leak for FLV stream caster. 2.0.237
* v2.0, 2017-04-15, Merge [#841][bug #841], avoid the duplicated sps/pps in ts. 2.0.236
* v2.0, 2017-04-09, Fix [#834][bug #834], crash for TS context corrupt. 2.0.235
... ... @@ -1285,6 +1286,7 @@ Winlin
[bug #834]: https://github.com/ossrs/srs/issues/834
[bug #841]: https://github.com/ossrs/srs/issues/841
[bug #846]: https://github.com/ossrs/srs/issues/846
[bug #844]: https://github.com/ossrs/srs/issues/844
[bug #xxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxx
[exo #828]: https://github.com/google/ExoPlayer/pull/828
... ...
... ... @@ -546,6 +546,16 @@ int SrsRtmpConn::stream_service_cycle()
return publishing(source);
}
case SrsRtmpConnHaivisionPublish: {
srs_verbose("Haivision start to publish stream %s.", req->stream.c_str());
if ((ret = rtmp->start_haivision_publish(res->stream_id)) != ERROR_SUCCESS) {
srs_error("start to publish stream failed. ret=%d", ret);
return ret;
}
return publishing(source);
}
case SrsRtmpConnFlashPublish: {
srs_verbose("flash start to publish stream %s.", req->stream.c_str());
... ... @@ -839,7 +849,7 @@ int SrsRtmpConn::publishing(SrsSource* source)
// @see: https://github.com/ossrs/srs/issues/237
SrsPublishRecvThread trd(rtmp, req,
st_netfd_fileno(stfd), 0, this, source,
client_type == SrsRtmpConnFMLEPublish,
client_type != SrsRtmpConnFlashPublish,
vhost_is_edge);
srs_info("start to publish stream %s success", req->stream.c_str());
... ...
... ... @@ -90,6 +90,7 @@ int SrsSecurity::allow_check(SrsConfDirective* rules, SrsRtmpConnType type, std:
break;
case SrsRtmpConnFMLEPublish:
case SrsRtmpConnFlashPublish:
case SrsRtmpConnHaivisionPublish:
if (rule->arg0() != "publish") {
break;
}
... ... @@ -135,6 +136,7 @@ int SrsSecurity::deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std::
break;
case SrsRtmpConnFMLEPublish:
case SrsRtmpConnFlashPublish:
case SrsRtmpConnHaivisionPublish:
if (rule->arg0() != "publish") {
break;
}
... ...
... ... @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// current release version
#define VERSION_MAJOR 2
#define VERSION_MINOR 0
#define VERSION_REVISION 237
#define VERSION_REVISION 238
// generated by configure, only macros.
#include <srs_auto_headers.hpp>
... ...
... ... @@ -1791,6 +1791,7 @@ string srs_client_type_string(SrsRtmpConnType type)
case SrsRtmpConnPlay: return "Play";
case SrsRtmpConnFlashPublish: return "flash-publish";
case SrsRtmpConnFMLEPublish: return "fmle-publish";
case SrsRtmpConnHaivisionPublish: return "haivision-publish";
default: return "Unknown";
}
}
... ... @@ -2693,6 +2694,14 @@ int SrsRtmpServer::identify_client(int stream_id, SrsRtmpConnType& type, string&
}
return ret;
}
// For encoder of Haivision, it always send a _checkbw call message.
// @Remark the next message is createStream, so we continue to identify it.
// @see https://github.com/ossrs/srs/issues/844
if (call->command_name == "_checkbw") {
srs_info("Haivision encoder identified.");
continue;
}
continue;
}
... ... @@ -2968,6 +2977,60 @@ int SrsRtmpServer::start_fmle_publish(int stream_id)
return ret;
}
int SrsRtmpServer::start_haivision_publish(int stream_id)
{
int ret = ERROR_SUCCESS;
// publish
if (true) {
SrsCommonMessage* msg = NULL;
SrsPublishPacket* pkt = NULL;
if ((ret = expect_message<SrsPublishPacket>(&msg, &pkt)) != ERROR_SUCCESS) {
srs_error("recv publish message failed. ret=%d", ret);
return ret;
}
srs_info("recv publish request message success.");
SrsAutoFree(SrsCommonMessage, msg);
SrsAutoFree(SrsPublishPacket, pkt);
}
// publish response onFCPublish(NetStream.Publish.Start)
if (true) {
SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
pkt->command_name = RTMP_AMF0_COMMAND_ON_FC_PUBLISH;
pkt->data->set(StatusCode, SrsAmf0Any::str(StatusCodePublishStart));
pkt->data->set(StatusDescription, SrsAmf0Any::str("Started publishing stream."));
if ((ret = protocol->send_and_free_packet(pkt, stream_id)) != ERROR_SUCCESS) {
srs_error("send onFCPublish(NetStream.Publish.Start) message failed. ret=%d", ret);
return ret;
}
srs_info("send onFCPublish(NetStream.Publish.Start) message success.");
}
// publish response onStatus(NetStream.Publish.Start)
if (true) {
SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
pkt->data->set(StatusLevel, SrsAmf0Any::str(StatusLevelStatus));
pkt->data->set(StatusCode, SrsAmf0Any::str(StatusCodePublishStart));
pkt->data->set(StatusDescription, SrsAmf0Any::str("Started publishing stream."));
pkt->data->set(StatusClientId, SrsAmf0Any::str(RTMP_SIG_CLIENT_ID));
if ((ret = protocol->send_and_free_packet(pkt, stream_id)) != ERROR_SUCCESS) {
srs_error("send onStatus(NetStream.Publish.Start) message failed. ret=%d", ret);
return ret;
}
srs_info("send onStatus(NetStream.Publish.Start) message success.");
}
srs_info("Haivision publish success.");
return ret;
}
int SrsRtmpServer::fmle_unpublish(int stream_id, double unpublish_tid)
{
int ret = ERROR_SUCCESS;
... ... @@ -3102,6 +3165,10 @@ int SrsRtmpServer::identify_create_stream_client(SrsCreateStreamPacket* req, int
srs_info("identify client by create stream, play or flash publish.");
return identify_create_stream_client(dynamic_cast<SrsCreateStreamPacket*>(pkt), stream_id, type, stream_name, duration);
}
if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) {
srs_info("identify client by FCPublish, haivision publish.");
return identify_haivision_publish_client(dynamic_cast<SrsFMLEStartPacket*>(pkt), type, stream_name);
}
srs_trace("ignore AMF0/AMF3 command message.");
}
... ... @@ -3129,6 +3196,26 @@ int SrsRtmpServer::identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsRtmp
return ret;
}
int SrsRtmpServer::identify_haivision_publish_client(SrsFMLEStartPacket* req, SrsRtmpConnType& type, string& stream_name)
{
int ret = ERROR_SUCCESS;
type = SrsRtmpConnHaivisionPublish;
stream_name = req->stream_name;
// FCPublish response
if (true) {
SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(req->transaction_id);
if ((ret = protocol->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
srs_error("send FCPublish response message failed. ret=%d", ret);
return ret;
}
srs_info("send FCPublish response message success.");
}
return ret;
}
int SrsRtmpServer::identify_flash_publish_client(SrsPublishPacket* req, SrsRtmpConnType& type, string& stream_name)
{
int ret = ERROR_SUCCESS;
... ...
... ... @@ -69,6 +69,7 @@ class SrsCommonMessage;
class SrsPacket;
class SrsAmf0Object;
class IMergeReadHandler;
class SrsCallPacket;
/****************************************************************************
*****************************************************************************
... ... @@ -631,6 +632,7 @@ enum SrsRtmpConnType
SrsRtmpConnPlay,
SrsRtmpConnFMLEPublish,
SrsRtmpConnFlashPublish,
SrsRtmpConnHaivisionPublish,
};
std::string srs_client_type_string(SrsRtmpConnType type);
bool srs_client_type_is_publish(SrsRtmpConnType type);
... ... @@ -990,6 +992,11 @@ public:
*/
virtual int start_fmle_publish(int stream_id);
/**
* For encoder of Haivision, response the startup request.
* @see https://github.com/ossrs/srs/issues/844
*/
virtual int start_haivision_publish(int stream_id);
/**
* process the FMLE unpublish event.
* @unpublish_tid the unpublish request transaction id.
*/
... ... @@ -1025,6 +1032,7 @@ public:
private:
virtual int identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsRtmpConnType& type, std::string& stream_name, double& duration);
virtual int identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsRtmpConnType& type, std::string& stream_name);
virtual int identify_haivision_publish_client(SrsFMLEStartPacket* req, SrsRtmpConnType& type, std::string& stream_name);
virtual int identify_flash_publish_client(SrsPublishPacket* req, SrsRtmpConnType& type, std::string& stream_name);
private:
virtual int identify_play_client(SrsPlayPacket* req, SrsRtmpConnType& type, std::string& stream_name, double& duration);
... ... @@ -1293,7 +1301,7 @@ public:
};
/**
* FMLE start publish: ReleaseStream/PublishStream
* FMLE start publish: ReleaseStream/PublishStream/FCPublish/FCUnpublish
*/
class SrsFMLEStartPacket : public SrsPacket
{
... ...